// Copyright (c) 2017 PSForever
package game.objectcreatedetailed

import net.psforever.objects.avatar.{BattleRank, Certification}
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game.ObjectCreateDetailedMessage
import net.psforever.packet.game.objectcreate._
import net.psforever.types._
import scodec.bits._

class DetailedCharacterDataTest extends Specification {
  val string =
    hex"18 570C0000 BC8 4B00 6C2D7 65535 CA16 0 00 01 34 40 00 0970 49006C006C006C004900490049006C006C006C0049006C0049006C006C0049006C006C006C0049006C006C004900 84 52 70 76 1E 80 80 00 00 00 00 00 3FFFC 0 00 00 00 20 00 00 0F F6 A7 03 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 90 01 90 00 64 00 00 01 00 7E C8 00 C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 C0 00 42 C5 46  86 C7 00 00 00 80 00 00 12 40 78 70 65 5F 73 61 6E 63 74 75 61 72 79 5F 68 65 6C 70 90 78 70 65 5F 74 68 5F 66 69 72 65 6D 6F 64 65 73 8B 75 73 65 64 5F 62 65 61 6D 65 72 85 6D 61 70 31 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 0A 23 02 60 04 04 40 00 00 10 00 06 02 08 14 D0 08 0C 80 00 02 00 02 6B 4E 00 82 88 00 00 02 00 00 C0 41 C0 9E 01 01 90 00 00 64 00 44 2A 00 10 91 00 00 00 40 00 18 08 38 94 40 20 32 00 00 00 80 19 05 48 02 17 20 00 00 08 00 70 29 80 43 64 00 00 32 00 0E 05 40 08 9C 80 00 06 40 01 C0 AA 01 19 90 00 00 C8 00 3A 15 80 28 72 00 00 19 00 04 0A B8 05 26 40 00 03 20 06 C2 58 00 A7 88 00 00 02 00 00 80 00 00"
  val string_seated =
    hex"181f0c000066d5bc84b00808000012e049006c006c006c004900490049006c006c006c0049006c0049006c006c0049006c006c006c004900" ++
      hex"6c006c0049008452700000000000000000000000000000002000000fe6a703fffffffffffffffffffffffffffffffc000000000000000000" ++
      hex"00000000000000000000019001900064000001007ec800c80000000000000000000000000000000000000001c00042c54686c70000008000" ++
      hex"0012407870655f73616e6374756172795f68656c70907870655f74685f666972656d6f6465738b757365645f6265616d6572856d61703133" ++
      hex"0000000000000000000000000000000000000000000000000000000000010a2302600404400000100006020814d0080c80000200026b4e00" ++
      hex"82880000020000c041c09e01019000006400442a001091000000400018083894402032000000801905480217200000080070298043640000" ++
      hex"32000e0540089c8000064001c0aa0119900000c8003a1580287200001900040ab805264000032006c25800a7880000020000800000"
  val string_max =
    hex"187d280000bc8010063cb74a247ad390000080400008a048006100480061004100540052004d00610078004a727bb69e808000000000003f" ++
      hex"ffc000000020000000400703ffffffffffffffffffffffffffffffff14ec000000000000000000000000000000000001e001e00102040001" ++
      hex"007ec800c800000000000000000000000000000000000000000000000140004686c840000600000012207870655f626174746c655f72616e" ++
      hex"6b5f33917870655f62696e645f666163696c697479927870655f696e7374616e745f616374696f6e917870655f626174746c655f72616e6b" ++
      hex"5f34917870655f626174746c655f72616e6b5f32927870655f73616e6374756172795f68656c708c7870655f64726f705f706f6493787065" ++
      hex"5f6f72626974616c5f73687574746c65917870655f626174746c655f72616e6b5f358e7870655f74685f6e6f6e73616e638f7870655f7468" ++
      hex"5f67726f756e645f708b7870655f74685f616d6d6f907870655f74685f666972656d6f6465738a7870655f74685f6d617897766973697465" ++
      hex"645f73706974666972655f74757272657493766973697465645f77616c6c5f74757272657495766973697465645f7265736f757263655f73" ++
      hex"696c6f9e766973697465645f63657274696669636174696f6e5f7465726d696e616c94766973697465645f6d65645f7465726d696e616c9a" ++
      hex"766973697465645f62726f6164636173745f77617270676174658c757365645f7068616c616e789c766973697465645f6169725f76656869" ++
      hex"636c655f7465726d696e616c94766973697465645f6266725f7465726d696e616c8b757365645f6379636c657297766973697465645f6761" ++
      hex"6c6178795f7465726d696e616c98766973697465645f696d706c616e745f7465726d696e616c9a766973697465645f65787465726e616c5f" ++
      hex"646f6f725f6c6f636b98766973697465645f7265737061776e5f7465726d696e616c8e766973697465645f6c6f636b657295766973697465" ++
      hex"645f6d6f74696f6e5f73656e736f7293757365645f6772656e6164655f706c61736d6188757365645f72656b8d757365645f726570656174" ++
      hex"65729f766973697465645f6465636f6e737472756374696f6e5f7465726d696e616c99766973697465645f7365636f6e646172795f636170" ++
      hex"747572658f757365645f73757070726573736f7292757365645f74726865765f6275727374657295757365645f74726865765f6475616c63" ++
      hex"79636c657292757365645f74726865765f706f756e64657298766973697465645f636170747572655f7465726d696e616c96766973697465" ++
      hex"645f6f726465725f7465726d696e616c9f766973697465645f67726f756e645f76656869636c655f7465726d696e616c856d61703132856d" ++
      hex"61703130856d61703039856d61703035856d61703033856d6170303200000000000000000000000000000000000000000000000000000000" ++
      hex"0001131e5810040040000010000606049030080c800019000092080103900003200012414020b20000640015e01802102000000800030107" ++
      hex"10380406400000100320840042e400000100049090086c80000480009214011590000190001242c023b20000320002486004964000064000" ++
      hex"490d00c6c80000c8000921c019590000190001243c033b20000320002488006964000064000c211000086c80000020018424000115900000" ++
      hex"04003084c00023b2000000800610a00004964000001000c2150000a6c8000002001842c00015590000004003085c0002bb2000000800610c" ++
      hex"000059640000010000"
  val string_br32 =
    hex"18 2c e0 00 00 bc 84 B0 00 0b ea 00 6c 7d f1 10 00 00 02 40 00 08 60 4b 00 69 00 43 00 6b 00 4a 00 72 00 02 31 3a cc 82 c0 00 00 00 00 00 00 00 00 3e df 42 00 20 00 0e 00 40 43 40 4c 04 00 02 e8 00 00 03 a8 00 00 01 9c 04 00 00 b8 99 84 00 0e 68 28 00 00 00 00 00 00 00 00 00 00 00 00 01 90 01 90 00 c8 00 00 01 00 7e c8 00 5c 00 00 01 29 c1 cc 80 00 00 00 00 00 00 00 00 00 00 00 00 03 c0 00 40 81 01 c4 45 46 86 c8 88 c9 09 4a 4a 80 50 0c 13 00 00 15 00 80 00 48 00 7870655f6f766572686561645f6d6170  "
  val string_ccrider =
    hex"18 4a c7 00 00 bc 84 B0 0c 0b 95 59 9a 84 40 b0 00 01 32 00 00 08 70 43 00 43 00 52 00 49 00 44 00 45 00 52 00 82 28 c9 3d 04 40 03 c0 01 40 02 80 00 40 35 18 40 00 25 40 42 00 6c 00 61 00 63 00 6b 00 20 00 41 00 72 00 6d 00 6f 00 72 00 65 00 64 00 20 00 52 00 65 00 61 00 70 00 65 00 72 00 73 00 0f 00 00 03 02 0c 00 00 03 88 00 00 00 d4 00 00 01 9c 04 00 00 09 19 90 02 04 3c 28 00 00 00 00 00 00 00 00 00 00 00 00 01 90 01 90 00 64 00 00 01 00 7e c8 00 c8 00 00 01 b9 53 4c 00 00 00 00 00 00 00 00 00 00 00 00 00 03 40 00 40 81 c6 86 c8 48 88 c9 09 49 8a 67 86 e0 00 01 25 e0 32 d8 09 6c 00 00 3c 04 00 02 30  "
  val string_xrider912 =
    hex" "

  "DetailedCharacterData" should {
    "decode" in {
      PacketCoding.decodePacket(string).require match {
        case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
          len mustEqual 3159
          cls mustEqual ObjectClass.avatar
          guid mustEqual PlanetSideGUID(75)
          parent.isDefined mustEqual false
          data match {
            case DetailedPlayerData(Some(pos), basic, char, inv, hand) =>
              pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
              pos.orient mustEqual Vector3(0, 0, 36.5625f)
              pos.vel.isDefined mustEqual false

              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app.name mustEqual "IlllIIIlllIlIllIlllIllI"
                  a.app.faction mustEqual PlanetSideEmpire.VS
                  a.app.sex mustEqual CharacterSex.Female
                  a.app.head mustEqual 41
                  a.app.voice mustEqual CharacterVoice.Voice1
                  a.data.bops mustEqual false
                  a.data.v1 mustEqual true
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.Standard
                  a.unk5 mustEqual 0
                  a.char_id mustEqual 41605313L
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0
                  a.unk9 mustEqual 0
                  a.unkA mustEqual 65535

                  b.outfit_id mustEqual 0L
                  b.outfit_name mustEqual ""
                  b.outfit_logo mustEqual 0
                  b.backpack mustEqual false
                  b.facingPitch mustEqual 2.8125f
                  b.facingYawUpper mustEqual 61.875f
                  b.lfs mustEqual true
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.charging_pose mustEqual false
                  b.on_zipline.isEmpty mustEqual true
                  b.unk1 mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.unk5 mustEqual false
                  b.unk6 mustEqual false
                  b.unk7 mustEqual false

                  ribbons.upper mustEqual MeritCommendation.None
                  ribbons.middle mustEqual MeritCommendation.None
                  ribbons.lower mustEqual MeritCommendation.None
                  ribbons.tos mustEqual MeritCommendation.None
                case _ =>
                  ko
              }

              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 0L
                  a.cep mustEqual 0L
                  a.healthMax mustEqual 100
                  a.health mustEqual 100
                  a.armor mustEqual 50 //standard exosuit value
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 100
                  a.max_field.isEmpty mustEqual true
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.ATV,
                    Certification.Harasser,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.ReinforcedExoSuit
                  )
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.unk4 mustEqual false
                  a.unk5 mustEqual 32831L
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)

                  b.implants mustEqual List()
                  b.firstTimeEvents mustEqual List(
                    "xpe_sanctuary_help",
                    "xpe_th_firemodes",
                    "used_beamer",
                    "map13"
                  )
                  b.tutorials mustEqual Nil
                  b.cosmetics.isEmpty mustEqual true
                  b.unk1.isEmpty mustEqual true
                  b.unk2 mustEqual Nil
                  b.unk3 mustEqual Nil
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
                  b.unkA mustEqual Nil
                  b.unkB mustEqual Nil
                  b.unkC mustEqual false
                case _ =>
                  ko
              }

              inv.isDefined mustEqual true
              val inventory = inv.get.contents
              inventory.size mustEqual 10
              //0
              inventory.head.objectClass mustEqual ObjectClass.beamer
              inventory.head.guid mustEqual PlanetSideGUID(76)
              inventory.head.parentSlot mustEqual 0
              var wep = inventory.head.obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.energy_cell
              wep.ammo.head.guid mustEqual PlanetSideGUID(77)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 16
              //1
              inventory(1).objectClass mustEqual ObjectClass.suppressor
              inventory(1).guid mustEqual PlanetSideGUID(78)
              inventory(1).parentSlot mustEqual 2
              wep = inventory(1).obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
              wep.ammo.head.guid mustEqual PlanetSideGUID(79)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 25
              //2
              inventory(2).objectClass mustEqual ObjectClass.forceblade
              inventory(2).guid mustEqual PlanetSideGUID(80)
              inventory(2).parentSlot mustEqual 4
              wep = inventory(2).obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.melee_ammo
              wep.ammo.head.guid mustEqual PlanetSideGUID(81)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 1
              //3
              inventory(3).objectClass mustEqual ObjectClass.locker_container
              inventory(3).guid mustEqual PlanetSideGUID(82)
              inventory(3).parentSlot mustEqual 5
              inventory(3).obj.isInstanceOf[DetailedLockerContainerData] mustEqual true
              inventory(3).obj.asInstanceOf[DetailedLockerContainerData].inventory.isDefined mustEqual false
              //4
              inventory(4).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(4).guid mustEqual PlanetSideGUID(83)
              inventory(4).parentSlot mustEqual 6
              inventory(4).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //5
              inventory(5).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(5).guid mustEqual PlanetSideGUID(84)
              inventory(5).parentSlot mustEqual 9
              inventory(5).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //6
              inventory(6).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(6).guid mustEqual PlanetSideGUID(85)
              inventory(6).parentSlot mustEqual 12
              inventory(6).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //7
              inventory(7).objectClass mustEqual ObjectClass.bullet_9mm_AP
              inventory(7).guid mustEqual PlanetSideGUID(86)
              inventory(7).parentSlot mustEqual 33
              inventory(7).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //8
              inventory(8).objectClass mustEqual ObjectClass.energy_cell
              inventory(8).guid mustEqual PlanetSideGUID(87)
              inventory(8).parentSlot mustEqual 36
              inventory(8).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //9
              inventory(9).objectClass mustEqual ObjectClass.remote_electronics_kit
              inventory(9).guid mustEqual PlanetSideGUID(88)
              inventory(9).parentSlot mustEqual 39
              //the rek has data but none worth testing here
              hand mustEqual DrawnSlot.Pistol1
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "decode (character, seated)" in {
      PacketCoding.decodePacket(string_seated).require match {
        case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
          len mustEqual 3103
          cls mustEqual ObjectClass.avatar
          guid mustEqual PlanetSideGUID(75)
          parent.isDefined mustEqual true
          parent.get.guid mustEqual PlanetSideGUID(43981)
          parent.get.slot mustEqual 0
          data match {
            case DetailedPlayerData(None, basic, char, inv, hand) =>
              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app.name mustEqual "IlllIIIlllIlIllIlllIllI"
                  a.app.faction mustEqual PlanetSideEmpire.VS
                  a.app.sex mustEqual CharacterSex.Female
                  a.app.head mustEqual 41
                  a.app.voice mustEqual CharacterVoice.Voice1
                  a.data.bops mustEqual false
                  a.data.v1 mustEqual false
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.Standard
                  a.unk5 mustEqual 0
                  a.char_id mustEqual 192L
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0
                  a.unk9 mustEqual 0
                  a.unkA mustEqual 0

                  b.outfit_id mustEqual 0L
                  b.outfit_name mustEqual ""
                  b.outfit_logo mustEqual 0
                  b.backpack mustEqual false
                  b.facingPitch mustEqual 5.625f
                  b.facingYawUpper mustEqual 61.875f
                  b.lfs mustEqual true
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.charging_pose mustEqual false
                  b.on_zipline.isEmpty mustEqual true
                  b.unk1 mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.unk5 mustEqual false
                  b.unk6 mustEqual false
                  b.unk7 mustEqual false

                  ribbons.upper mustEqual MeritCommendation.None
                  ribbons.middle mustEqual MeritCommendation.None
                  ribbons.lower mustEqual MeritCommendation.None
                  ribbons.tos mustEqual MeritCommendation.None
                case _ =>
                  ko
              }

              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 0L
                  a.cep mustEqual 0L
                  a.healthMax mustEqual 100
                  a.health mustEqual 100
                  a.armor mustEqual 50 //standard exosuit value
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 100
                  a.max_field.isEmpty mustEqual true
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.ATV,
                    Certification.Harasser,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.ReinforcedExoSuit
                  )
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.unk4 mustEqual false
                  a.unk5 mustEqual 32831L
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)

                  b.implants mustEqual List()
                  b.firstTimeEvents mustEqual List(
                    "xpe_sanctuary_help",
                    "xpe_th_firemodes",
                    "used_beamer",
                    "map13"
                  )
                  b.tutorials mustEqual Nil
                  b.cosmetics.isEmpty mustEqual true
                  b.unk1.isEmpty mustEqual true
                  b.unk2 mustEqual Nil
                  b.unk3 mustEqual Nil
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
                  b.unkA mustEqual Nil
                  b.unkB mustEqual Nil
                  b.unkC mustEqual false
                case _ =>
                  ko
              }

              inv.isDefined mustEqual true
              val inventory = inv.get.contents
              inventory.size mustEqual 10
              //0
              inventory.head.objectClass mustEqual ObjectClass.beamer
              inventory.head.guid mustEqual PlanetSideGUID(76)
              inventory.head.parentSlot mustEqual 0
              var wep = inventory.head.obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.energy_cell
              wep.ammo.head.guid mustEqual PlanetSideGUID(77)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 16
              //1
              inventory(1).objectClass mustEqual ObjectClass.suppressor
              inventory(1).guid mustEqual PlanetSideGUID(78)
              inventory(1).parentSlot mustEqual 2
              wep = inventory(1).obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
              wep.ammo.head.guid mustEqual PlanetSideGUID(79)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 25
              //2
              inventory(2).objectClass mustEqual ObjectClass.forceblade
              inventory(2).guid mustEqual PlanetSideGUID(80)
              inventory(2).parentSlot mustEqual 4
              wep = inventory(2).obj.asInstanceOf[DetailedWeaponData]
              wep.ammo.head.objectClass mustEqual ObjectClass.melee_ammo
              wep.ammo.head.guid mustEqual PlanetSideGUID(81)
              wep.ammo.head.parentSlot mustEqual 0
              wep.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 1
              //3
              inventory(3).objectClass mustEqual ObjectClass.locker_container
              inventory(3).guid mustEqual PlanetSideGUID(82)
              inventory(3).parentSlot mustEqual 5
              inventory(3).obj.isInstanceOf[DetailedLockerContainerData] mustEqual true
              inventory(3).obj.asInstanceOf[DetailedLockerContainerData].inventory.isDefined mustEqual false
              //4
              inventory(4).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(4).guid mustEqual PlanetSideGUID(83)
              inventory(4).parentSlot mustEqual 6
              inventory(4).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //5
              inventory(5).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(5).guid mustEqual PlanetSideGUID(84)
              inventory(5).parentSlot mustEqual 9
              inventory(5).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //6
              inventory(6).objectClass mustEqual ObjectClass.bullet_9mm
              inventory(6).guid mustEqual PlanetSideGUID(85)
              inventory(6).parentSlot mustEqual 12
              inventory(6).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //7
              inventory(7).objectClass mustEqual ObjectClass.bullet_9mm_AP
              inventory(7).guid mustEqual PlanetSideGUID(86)
              inventory(7).parentSlot mustEqual 33
              inventory(7).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //8
              inventory(8).objectClass mustEqual ObjectClass.energy_cell
              inventory(8).guid mustEqual PlanetSideGUID(87)
              inventory(8).parentSlot mustEqual 36
              inventory(8).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
              //9
              inventory(9).objectClass mustEqual ObjectClass.remote_electronics_kit
              inventory(9).guid mustEqual PlanetSideGUID(88)
              inventory(9).parentSlot mustEqual 39
              //the rek has data but none worth testing here
              hand mustEqual DrawnSlot.Pistol1
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "decode (max)" in {
      PacketCoding.decodePacket(string_max).require match {
        case ObjectCreateDetailedMessage(_, _, _, _, data) =>
          //this test is mainly for an alternate bitstream parsing order
          //the object produced is massive and most of it is already covered in other tests
          //only certain details towards the end of the stream will be checked
          data match {
            case DetailedPlayerData(Some(_), basic, char, inv, hand) =>
              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app.name mustEqual "HaHaATRMax"
                  a.app.faction mustEqual PlanetSideEmpire.TR
                  a.app.sex mustEqual CharacterSex.Male
                  a.app.head mustEqual 57
                  a.app.voice mustEqual CharacterVoice.Voice1
                  a.data.bops mustEqual false
                  a.data.v1 mustEqual true
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.MAX
                  a.unk5 mustEqual 1
                  a.char_id mustEqual 41605870L
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0
                  a.unk9 mustEqual 0
                  a.unkA mustEqual 65535

                  b.outfit_id mustEqual 0L
                  b.outfit_name mustEqual ""
                  b.outfit_logo mustEqual 0
                  b.backpack mustEqual false
                  b.facingPitch mustEqual -11.25f
                  b.facingYawUpper mustEqual 0
                  b.lfs mustEqual true
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.charging_pose mustEqual false
                  b.on_zipline.isEmpty mustEqual true
                  b.unk1 mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.unk5 mustEqual false
                  b.unk6 mustEqual false
                  b.unk7 mustEqual false

                  ribbons.upper mustEqual MeritCommendation.None
                  ribbons.middle mustEqual MeritCommendation.None
                  ribbons.lower mustEqual MeritCommendation.None
                  ribbons.tos mustEqual MeritCommendation.None
                case _ =>
                  ko
              }

              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 15301L
                  a.cep mustEqual 0L
                  a.healthMax mustEqual 120
                  a.health mustEqual 120
                  a.armor mustEqual 641
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 100
                  a.max_field.contains(0) mustEqual true //important!
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.UniMAX
                  )
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.unk4 mustEqual false
                  a.unk5 mustEqual 32831L
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)

                  b.implants mustEqual Nil
                  b.firstTimeEvents mustEqual List(
                    "xpe_battle_rank_3",
                    "xpe_bind_facility",
                    "xpe_instant_action",
                    "xpe_battle_rank_4",
                    "xpe_battle_rank_2",
                    "xpe_sanctuary_help",
                    "xpe_drop_pod",
                    "xpe_orbital_shuttle",
                    "xpe_battle_rank_5",
                    "xpe_th_nonsanc",
                    "xpe_th_ground_p",
                    "xpe_th_ammo",
                    "xpe_th_firemodes",
                    "xpe_th_max",
                    "visited_spitfire_turret",
                    "visited_wall_turret",
                    "visited_resource_silo",
                    "visited_certification_terminal",
                    "visited_med_terminal",
                    "visited_broadcast_warpgate",
                    "used_phalanx",
                    "visited_air_vehicle_terminal",
                    "visited_bfr_terminal",
                    "used_cycler",
                    "visited_galaxy_terminal",
                    "visited_implant_terminal",
                    "visited_external_door_lock",
                    "visited_respawn_terminal",
                    "visited_locker",
                    "visited_motion_sensor",
                    "used_grenade_plasma",
                    "used_rek",
                    "used_repeater",
                    "visited_deconstruction_terminal",
                    "visited_secondary_capture",
                    "used_suppressor",
                    "used_trhev_burster",
                    "used_trhev_dualcycler",
                    "used_trhev_pounder",
                    "visited_capture_terminal",
                    "visited_order_terminal",
                    "visited_ground_vehicle_terminal",
                    "map12",
                    "map10",
                    "map09",
                    "map05",
                    "map03",
                    "map02"
                  )
                  b.tutorials mustEqual Nil
                  b.cosmetics.isEmpty mustEqual true
                  b.unk1.isEmpty mustEqual true
                  b.unk2 mustEqual Nil
                  b.unk3 mustEqual Nil
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
                  b.unkA mustEqual Nil
                  b.unkB mustEqual Nil
                  b.unkC mustEqual false
                case _ =>
                  ko
              }
              //inventory
              inv.isDefined mustEqual true
              inv.get.contents.size mustEqual 19
              val contents = inv.get.contents
              //0
              contents.head mustEqual InternalSlot(
                889,
                PlanetSideGUID(2),
                0,
                DetailedWeaponData(
                  CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
                  0,
                  List(
                    InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8, 200)),
                    InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8, 200)),
                    InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8, 200))
                  )
                )
              )
              contents(1) mustEqual InternalSlot(
                175,
                PlanetSideGUID(6),
                4,
                DetailedWeaponData(
                  CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
                  0,
                  List(
                    InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8, 1))
                  )
                )
              )
              contents(2) mustEqual InternalSlot(
                456,
                PlanetSideGUID(8),
                5,
                DetailedLockerContainerData(
                  CommonFieldData(
                    PlanetSideEmpire.NEUTRAL,
                    false,
                    false,
                    true,
                    None,
                    false,
                    None,
                    None,
                    PlanetSideGUID(0)
                  ),
                  None
                )
              )
              contents(3) mustEqual InternalSlot(265, PlanetSideGUID(9), 6, DetailedAmmoBoxData(8, 36))
              contents(4) mustEqual InternalSlot(265, PlanetSideGUID(10), 10, DetailedAmmoBoxData(8, 100))
              contents(5) mustEqual InternalSlot(265, PlanetSideGUID(11), 14, DetailedAmmoBoxData(8, 100))
              contents(6) mustEqual InternalSlot(265, PlanetSideGUID(12), 18, DetailedAmmoBoxData(8, 100))
              contents(7) mustEqual InternalSlot(265, PlanetSideGUID(13), 70, DetailedAmmoBoxData(8, 100))
              contents(8) mustEqual InternalSlot(265, PlanetSideGUID(14), 74, DetailedAmmoBoxData(8, 100))
              contents(9) mustEqual InternalSlot(265, PlanetSideGUID(15), 78, DetailedAmmoBoxData(8, 100))
              contents(10) mustEqual InternalSlot(265, PlanetSideGUID(16), 82, DetailedAmmoBoxData(8, 100))
              contents(11) mustEqual InternalSlot(536, PlanetSideGUID(17), 134, DetailedAmmoBoxData(8, 1))
              contents(12) mustEqual InternalSlot(536, PlanetSideGUID(18), 138, DetailedAmmoBoxData(8, 1))
              contents(13) mustEqual InternalSlot(536, PlanetSideGUID(19), 142, DetailedAmmoBoxData(8, 1))
              contents(14) mustEqual InternalSlot(536, PlanetSideGUID(20), 146, DetailedAmmoBoxData(8, 1))
              contents(15) mustEqual InternalSlot(536, PlanetSideGUID(21), 166, DetailedAmmoBoxData(8, 1))
              contents(16) mustEqual InternalSlot(536, PlanetSideGUID(22), 170, DetailedAmmoBoxData(8, 1))
              contents(17) mustEqual InternalSlot(536, PlanetSideGUID(23), 174, DetailedAmmoBoxData(8, 1))
              contents(18) mustEqual InternalSlot(536, PlanetSideGUID(24), 178, DetailedAmmoBoxData(8, 1))

              hand mustEqual DrawnSlot.Pistol1
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "decode (BR32)" in {
      PacketCoding.decodePacket(string_br32).require match {
        case ObjectCreateDetailedMessage(_, _, _, _, data) =>
          //this test is mainly for an alternate bitstream parsing order
          //the object produced is massive and most of it is already covered in other tests
          //only certain details towards the end of the stream will be checked
          data match {
            case DetailedPlayerData(Some(_), basic, char, inv, hand) =>
              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app.name mustEqual "KiCkJr"
                  a.app.faction mustEqual PlanetSideEmpire.NC
                  a.app.sex mustEqual CharacterSex.Male
                  a.app.head mustEqual 24
                  a.app.voice mustEqual CharacterVoice.Voice4
                  a.data.bops mustEqual false
                  a.data.v1 mustEqual true
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.Agile
                  a.unk5 mustEqual 0
                  a.char_id mustEqual 733931L
                  a.unk7 mustEqual 0
                  a.unk8 mustEqual 0
                  a.unk9 mustEqual 0
                  a.unkA mustEqual 0

                  b.outfit_id mustEqual 556539L
                  b.outfit_name mustEqual ""
                  b.outfit_logo mustEqual 14
                  b.backpack mustEqual false
                  b.facingPitch mustEqual -11.25f
                  b.facingYawUpper mustEqual -11.25f
                  b.lfs mustEqual false
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.charging_pose mustEqual false
                  b.on_zipline.isEmpty mustEqual true
                  b.unk1 mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.unk5 mustEqual true
                  b.unk6 mustEqual false
                  b.unk7 mustEqual false

                  ribbons.upper mustEqual MeritCommendation.Loser4
                  ribbons.middle mustEqual MeritCommendation.EventNCElite
                  ribbons.lower mustEqual MeritCommendation.HeavyAssault6
                  ribbons.tos mustEqual MeritCommendation.SixYearNC
                case _ =>
                  ko
              }

              (char.a.bep >= BattleRank.BR24.experience) mustEqual true
              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 6366766L
                  a.cep mustEqual 694787L
                  a.healthMax mustEqual 100
                  a.health mustEqual 100
                  a.armor mustEqual 100 //standard exosuit value
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 46
                  a.max_field.isEmpty mustEqual true
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.HeavyAssault,
                    Certification.AntiVehicular,
                    Certification.AirCavalryScout,
                    Certification.GroundSupport,
                    Certification.Harasser,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.Medical,
                    Certification.AdvancedMedical,
                    Certification.Hacking,
                    Certification.AdvancedHacking,
                    Certification.Engineering,
                    Certification.CombatEngineering
                  )
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.unk4 mustEqual false
                  a.unk5 mustEqual 32831L
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 4
                  a.unk8 mustEqual 3278759L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)

                  b.implants mustEqual List(
                    ImplantEntry(ImplantType.AudioAmplifier, None, false),
                    ImplantEntry(ImplantType.Targeting, None, false),
                    ImplantEntry(ImplantType.Surge, None, false)
                  )
                  b.firstTimeEvents mustEqual List(
                    "xpe_overhead_map",
                    "xpe_warp_gate",
                    "xpe_form_outfit",
                    "xpe_blackops",
                    "xpe_command_rank_5",
                    "xpe_command_rank_3",
                    "xpe_sanctuary_help",
                    "xpe_battle_rank_13",
                    "xpe_battle_rank_12",
                    "xpe_battle_rank_10",
                    "xpe_battle_rank_14",
                    "xpe_battle_rank_15",
                    "xpe_orbital_shuttle",
                    "xpe_drop_pod",
                    "xpe_bind_facility",
                    "xpe_battle_rank_3",
                    "xpe_battle_rank_5",
                    "xpe_battle_rank_4",
                    "xpe_join_squad",
                    "xpe_form_squad",
                    "xpe_instant_action",
                    "xpe_battle_rank_2",
                    "xpe_warp_gate_usage",
                    "xpe_battle_rank_8",
                    "xpe_battle_rank_11",
                    "xpe_battle_rank_6",
                    "xpe_mail_alert",
                    "xpe_command_rank_1",
                    "xpe_battle_rank_20",
                    "xpe_battle_rank_18",
                    "xpe_battle_rank_19",
                    "xpe_join_platoon",
                    "xpe_battle_rank_17",
                    "xpe_battle_rank_16",
                    "xpe_join_outfit",
                    "xpe_battle_rank_25",
                    "xpe_battle_rank_24",
                    "xpe_command_rank_4",
                    "xpe_form_platoon",
                    "xpe_bind_ams",
                    "xpe_battle_rank_9",
                    "xpe_battle_rank_7",
                    "xpe_th_router",
                    "xpe_th_flail",
                    "xpe_th_ant",
                    "xpe_th_ams",
                    "xpe_th_ground_p",
                    "xpe_th_air_p",
                    "xpe_th_hover",
                    "xpe_th_ground",
                    "xpe_th_bfr",
                    "xpe_th_afterburner",
                    "xpe_th_air",
                    "xpe_th_cloak",
                    "used_oicw",
                    "used_advanced_ace",
                    "visited_spitfire_turret",
                    "visited_spitfire_cloaked",
                    "visited_spitfire_aa",
                    "visited_tank_traps",
                    "visited_portable_manned_turret_nc",
                    "visited_portable_manned_turret_tr",
                    "used_magcutter",
                    "used_chainblade",
                    "used_forceblade",
                    "visited_wall_turret",
                    "visited_ancient_terminal",
                    "visited_ams",
                    "visited_ant",
                    "visited_dropship",
                    "visited_liberator",
                    "visited_lightgunship",
                    "visited_lightning",
                    "visited_magrider",
                    "visited_prowler",
                    "visited_quadstealth",
                    "visited_skyguard",
                    "visited_threemanheavybuggy",
                    "visited_two_man_assault_buggy",
                    "visited_twomanheavybuggy",
                    "visited_twomanhoverbuggy",
                    "visited_vanguard",
                    "visited_flail",
                    "visited_router",
                    "visited_switchblade",
                    "visited_aurora",
                    "visited_battlewagon",
                    "visited_fury",
                    "visited_quadassault",
                    "visited_galaxy_gunship",
                    "visited_apc_tr",
                    "visited_apc_vs",
                    "visited_lodestar",
                    "visited_phantasm",
                    "visited_thunderer",
                    "visited_apc_nc",
                    "visited_vulture",
                    "visited_wasp",
                    "visited_mosquito",
                    "visited_aphelion_flight",
                    "visited_aphelion_gunner",
                    "visited_colossus_flight",
                    "visited_colossus_gunner",
                    "visited_peregrine_flight",
                    "visited_peregrine_gunner",
                    "used_bank",
                    "visited_resource_silo",
                    "visited_certification_terminal",
                    "visited_med_terminal",
                    "used_nano_dispenser",
                    "visited_sensor_shield",
                    "visited_broadcast_warpgate",
                    "used_phalanx",
                    "used_phalanx_avcombo",
                    "used_phalanx_flakcombo",
                    "visited_warpgate_small",
                    "used_flamethrower",
                    "used_ancient_turret_weapon",
                    "visited_LLU_socket",
                    "used_energy_gun_nc",
                    "visited_mediumtransport",
                    "used_aphelion_immolation_cannon",
                    "used_grenade_plasma",
                    "used_grenade_jammer",
                    "visited_shield_generator",
                    "visited_motion_sensor",
                    "visited_health_crystal",
                    "visited_repair_crystal",
                    "visited_vehicle_crystal",
                    "used_grenade_frag",
                    "used_ace",
                    "visited_adv_med_terminal",
                    "used_beamer",
                    "used_bolt_driver",
                    "used_cycler",
                    "used_gauss",
                    "used_hunterseeker",
                    "used_isp",
                    "used_lancer",
                    "used_lasher",
                    "used_maelstrom",
                    "used_phoenix",
                    "used_pulsar",
                    "used_punisher",
                    "used_r_shotgun",
                    "used_radiator",
                    "used_rek",
                    "used_repeater",
                    "used_rocklet",
                    "used_striker",
                    "used_suppressor",
                    "used_thumper",
                    "visited_vanu_control_console",
                    "visited_capture_terminal",
                    "used_mini_chaingun",
                    "used_laze_pointer",
                    "used_telepad",
                    "used_spiker",
                    "used_heavy_sniper",
                    "used_command_uplink",
                    "used_firebird",
                    "used_flechette",
                    "used_heavy_rail_beam",
                    "used_ilc9",
                    "visited_generator_terminal",
                    "visited_locker",
                    "visited_external_door_lock",
                    "visited_air_vehicle_terminal",
                    "visited_galaxy_terminal",
                    "visited_implant_terminal",
                    "visited_secondary_capture",
                    "used_25mm_cannon",
                    "used_liberator_bombardier",
                    "visited_repair_silo",
                    "visited_vanu_module",
                    "used_flail_weapon",
                    "used_scythe",
                    "visited_respawn_terminal",
                    "used_ballgun",
                    "used_energy_gun_tr",
                    "used_anniversary_guna",
                    "used_anniversary_gunb",
                    "used_anniversary_gun",
                    "used_75mm_cannon",
                    "used_apc_nc_weapon",
                    "used_apc_tr_weapon",
                    "used_apc_vs_weapon",
                    "used_flux_cannon",
                    "used_aphelion_plasma_rocket_pod",
                    "used_aphelion_ppa",
                    "used_fluxpod",
                    "visited_bfr_terminal",
                    "used_colossus_cluster_bomb_pod",
                    "used_colossus_dual_100mm_cannons",
                    "used_colossus_tank_cannon",
                    "visited_energy_crystal",
                    "used_heavy_grenade_launcher",
                    "used_35mm_rotarychaingun",
                    "used_katana",
                    "used_35mm_cannon",
                    "used_reaver_weapons",
                    "used_lightning_weapons",
                    "used_med_app",
                    "used_20mm_cannon",
                    "visited_monolith_amerish",
                    "visited_monolith_ceryshen",
                    "visited_monolith_cyssor",
                    "visited_monolith_esamir",
                    "visited_monolith_forseral",
                    "visited_monolith_ishundar",
                    "visited_monolith_searhus",
                    "visited_monolith_solsar",
                    "used_nc_hev_falcon",
                    "used_nc_hev_scattercannon",
                    "used_nc_hev_sparrow",
                    "used_armor_siphon",
                    "used_peregrine_dual_machine_gun",
                    "used_peregrine_dual_rocket_pods",
                    "used_peregrine_mechhammer",
                    "used_peregrine_particle_cannon",
                    "used_peregrine_sparrow",
                    "used_105mm_cannon",
                    "used_15mm_chaingun",
                    "used_pulsed_particle_accelerator",
                    "used_rotarychaingun",
                    "visited_deconstruction_terminal",
                    "used_skyguard_weapons",
                    "visited_generator",
                    "used_gauss_cannon",
                    "used_trek",
                    "used_vanguard_weapons",
                    "visited_ancient_air_vehicle_terminal",
                    "visited_ancient_equipment_terminal",
                    "visited_order_terminal",
                    "visited_ancient_ground_vehicle_terminal",
                    "visited_ground_vehicle_terminal",
                    "used_vulture_bombardier",
                    "used_vulture_nose_cannon",
                    "used_vulture_tail_cannon",
                    "used_wasp_weapon_system",
                    "visited_charlie01",
                    "visited_charlie02",
                    "visited_charlie03",
                    "visited_charlie04",
                    "visited_charlie05",
                    "visited_charlie06",
                    "visited_charlie07",
                    "visited_charlie08",
                    "visited_charlie09",
                    "visited_gingerman_atar",
                    "visited_gingerman_dahaka",
                    "visited_gingerman_hvar",
                    "visited_gingerman_izha",
                    "visited_gingerman_jamshid",
                    "visited_gingerman_mithra",
                    "visited_gingerman_rashnu",
                    "visited_gingerman_sraosha",
                    "visited_gingerman_yazata",
                    "visited_gingerman_zal",
                    "visited_sled01",
                    "visited_sled02",
                    "visited_sled04",
                    "visited_sled05",
                    "visited_sled06",
                    "visited_sled07",
                    "visited_sled08",
                    "visited_snowman_amerish",
                    "visited_snowman_ceryshen",
                    "visited_snowman_cyssor",
                    "visited_snowman_esamir",
                    "visited_snowman_forseral",
                    "visited_snowman_hossin",
                    "visited_snowman_ishundar",
                    "visited_snowman_searhus",
                    "visited_snowman_solsar",
                    "ugd06",
                    "ugd05",
                    "ugd04",
                    "ugd03",
                    "ugd02",
                    "ugd01",
                    "map99",
                    "map98",
                    "map97",
                    "map96",
                    "map15",
                    "map14",
                    "map11",
                    "map08",
                    "map04",
                    "map05",
                    "map03",
                    "map01",
                    "map06",
                    "map02",
                    "map09",
                    "map07",
                    "map10"
                  )
                  b.tutorials mustEqual List(
                    "training_start_nc",
                    "training_ui",
                    "training_map"
                  )
                  b.cosmetics must beSome(
                    beEqualTo(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
                  )
                  b.unk1.isEmpty mustEqual true
                  b.unk2 mustEqual Nil
                  b.unk3 mustEqual Nil
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.isEmpty mustEqual true
                  b.unkA mustEqual Nil
                  b.unkB mustEqual Nil
                  b.unkC mustEqual false
                case _ =>
                  ko
              }
              //inventory (but just briefly)
              inv.isDefined mustEqual true
              inv.get.contents.size mustEqual 12
              //0
              inv.get.contents.head.objectClass mustEqual 531
              inv.get.contents.head.guid mustEqual PlanetSideGUID(4202)
              inv.get.contents.head.parentSlot mustEqual 0
              inv.get.contents.head.obj match {
                case DetailedWeaponData(
                      CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid),
                      fmode,
                      ammo,
                      _
                    ) =>
                  faction mustEqual PlanetSideEmpire.NC
                  bops mustEqual false
                  alternate mustEqual false
                  v1 mustEqual true
                  v2.isEmpty mustEqual true
                  v3 mustEqual false
                  v4.isEmpty mustEqual true
                  v5.isEmpty mustEqual true
                  fguid mustEqual PlanetSideGUID(0)

                  fmode mustEqual 0

                  ammo.head.objectClass mustEqual 389
                  ammo.head.guid mustEqual PlanetSideGUID(3942)
                  ammo.head.parentSlot mustEqual 0
                  ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].data.v1 mustEqual true
                  ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 100
                case _ =>
                  ko
              }
              //4
              inv.get.contents(4).objectClass mustEqual 456
              inv.get.contents(4).guid mustEqual PlanetSideGUID(5374)
              inv.get.contents(4).parentSlot mustEqual 5
              inv.get.contents(4).obj.asInstanceOf[DetailedLockerContainerData].inventory.get.contents.size mustEqual 61
              //10
              inv.get.contents(10).objectClass mustEqual 32
              inv.get.contents(10).guid mustEqual PlanetSideGUID(5523)
              inv.get.contents(10).parentSlot mustEqual 39
              inv.get.contents(10).obj match {
                case cdata: DetailedConstructionToolData =>
                  cdata.data.faction mustEqual PlanetSideEmpire.NC
                  cdata.data.bops mustEqual false
                  cdata.data.alternate mustEqual false
                  cdata.data.v1 mustEqual true
                  cdata.data.v2.isEmpty mustEqual true
                  cdata.data.jammered mustEqual false
                  cdata.data.v4.isEmpty mustEqual true
                  cdata.data.v5.isEmpty mustEqual true
                  cdata.data.guid mustEqual PlanetSideGUID(0)
                case _ =>
                  ko
              }
              //11
              inv.get.contents(11).objectClass mustEqual 673
              inv.get.contents(11).guid mustEqual PlanetSideGUID(3661)
              inv.get.contents(11).parentSlot mustEqual 60
              inv.get.contents(11).obj match {
                case DetailedWeaponData(
                      CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid),
                      fmode,
                      ammo,
                      _
                    ) =>
                  faction mustEqual PlanetSideEmpire.NC
                  bops mustEqual false
                  alternate mustEqual false
                  v1 mustEqual true
                  v2.isEmpty mustEqual true
                  v3 mustEqual false
                  v4.isEmpty mustEqual true
                  v5.isEmpty mustEqual true
                  fguid mustEqual PlanetSideGUID(0)

                  fmode mustEqual 0

                  ammo.head.objectClass mustEqual 674
                  ammo.head.guid mustEqual PlanetSideGUID(8542)
                  ammo.head.parentSlot mustEqual 0
                  ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].data.v1 mustEqual true
                  ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 3
                case _ =>
                  ko
              }

              hand mustEqual DrawnSlot.None
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "decode (ccrider)" in {
      PacketCoding.decodePacket(string_ccrider).require match {
        case ObjectCreateDetailedMessage(len, _, _, None, data) =>
          len mustEqual 51018L
          data match {
            case DetailedPlayerData(_, basic, char, inv, _) =>
              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app mustEqual BasicCharacterData(
                    "CCRIDER",
                    PlanetSideEmpire.NC,
                    CharacterSex.Male,
                    20,
                    CharacterVoice.Voice3
                  )
                  a.data.bops mustEqual false
                  a.data.alternate mustEqual false
                  a.data.v1 mustEqual false
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.Standard
                  a.unk5 mustEqual 0
                  a.char_id mustEqual 1176612L
                  a.unk7 mustEqual 15
                  a.unk8 mustEqual 5
                  a.unk9 mustEqual 10
                  a.unkA mustEqual 1

                  b.outfit_id mustEqual 25044L
                  b.outfit_name mustEqual "Black Armored Reapers"
                  b.outfit_logo mustEqual 15
                  b.unk1 mustEqual false
                  b.backpack mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.facingPitch mustEqual 0
                  b.facingYawUpper mustEqual 0
                  b.lfs mustEqual false
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.unk5 mustEqual false
                  b.unk6 mustEqual false
                  b.charging_pose mustEqual false
                  b.unk7 mustEqual false
                  b.on_zipline.isEmpty mustEqual true

                  ribbons.upper mustEqual MeritCommendation.DefenseNC5
                  ribbons.middle mustEqual MeritCommendation.HackingSupport5
                  ribbons.lower mustEqual MeritCommendation.BFRAdvanced2
                  ribbons.tos mustEqual MeritCommendation.SixYearNC
                case _ =>
                  ko
              }

              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 6571522L
                  a.cep mustEqual 659329L
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.healthMax mustEqual 100
                  a.health mustEqual 100
                  a.unk4 mustEqual false
                  a.armor mustEqual 50
                  a.unk5 mustEqual 32831L
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 100
                  a.max_field.isEmpty mustEqual true
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 6
                  a.unk8 mustEqual 3165669L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.HeavyAssault,
                    Certification.AirCavalryScout,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.UniMAX,
                    Certification.Medical,
                    Certification.AdvancedMedical,
                    Certification.Hacking,
                    Certification.AdvancedHacking,
                    Certification.ExpertHacking,
                    Certification.Engineering
                  )

                  b.unk1.contains(14140) mustEqual true
                  b.implants mustEqual List(
                    ImplantEntry(ImplantType.Surge, Some(94), false),
                    ImplantEntry(ImplantType.DarklightVision, Some(91), false),
                    ImplantEntry(ImplantType.Targeting, Some(91), false)
                  )
                  b.unk2 mustEqual List()
                  b.unk3 mustEqual List()
                  b.firstTimeEvents.size mustEqual 271 //too many to bother listing; see encoding test
                  b.tutorials mustEqual List(
                    "training_weapons01",
                    "training_warpgates",
                    "training_map",
                    "training_inventory",
                    "training_healing",
                    "training_hart",
                    "training_armors",
                    "training_welcome"
                  )
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.isEmpty mustEqual true
                  b.unkA.size mustEqual 86
                  b.unkA mustEqual List(
                    9, 10, 11, 16, 17, 18, 30, 31, 32, 37, 38, 52, 53, 57, 69, 92, 99, 100, 107, 108, 109, 110, 114,
                    115, 116, 117, 118, 127, 128, 129, 130, 131, 156, 163, 171, 178, 179, 180, 181, 194, 195, 198, 201,
                    215, 216, 217, 222, 223, 224, 225, 226, 227, 229, 230, 243, 244, 257, 265, 266, 277, 278, 283, 284,
                    285, 286, 289, 290, 296, 313, 334, 341, 342, 359, 369, 376, 377, 384, 391, 392, 393, 394, 398, 408,
                    415, 420, 424
                  )
                  b.unkB mustEqual List()
                  b.unkC mustEqual false
                  b.cosmetics must beSome(
                    beEqualTo(Set(Cosmetic.NoHelmet, Cosmetic.Sunglasses, Cosmetic.Earpiece, Cosmetic.BrimmedCap))
                  )
                case _ =>
                  ko
              }
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "decode (xRider912)" in {
      PacketCoding.decodePacket(string_xrider912).require match {
        case ObjectCreateDetailedMessage(len, cls, guid, parentInfo, data) =>
          len mustEqual 36047
          cls mustEqual ObjectClass.avatar
          guid mustEqual PlanetSideGUID(3390)
          parentInfo.isEmpty mustEqual true

          data match {
            case DetailedPlayerData(Some(pos), basic, char, Some(inv), hand) =>
              pos mustEqual PlacementData(3577.1797f, 2712.25f, 35.78125f, 0, 0, 50.625f)

              basic match {
                case CharacterAppearanceData(a, b, ribbons) =>
                  a.app mustEqual BasicCharacterData(
                    "xRider912",
                    PlanetSideEmpire.TR,
                    CharacterSex.Male,
                    4,
                    CharacterVoice.Voice1
                  )
                  a.data.bops mustEqual false
                  a.data.alternate mustEqual false
                  a.data.v1 mustEqual false
                  a.data.v2.isEmpty mustEqual true
                  a.data.jammered mustEqual false
                  a.data.v4.isEmpty mustEqual true
                  a.data.v5.isEmpty mustEqual true
                  a.exosuit mustEqual ExoSuitType.Standard
                  a.unk5 mustEqual 0
                  a.char_id mustEqual 1267466L
                  a.unk7 mustEqual 3
                  a.unk8 mustEqual 3
                  a.unk9 mustEqual 0
                  a.unkA mustEqual 0

                  b.outfit_id mustEqual 16507L
                  b.outfit_name mustEqual "Hooked On Insanity"
                  b.outfit_logo mustEqual 5
                  b.unk1 mustEqual false
                  b.backpack mustEqual false
                  b.unk2 mustEqual false
                  b.unk3 mustEqual false
                  b.unk4 mustEqual false
                  b.facingPitch mustEqual 0
                  b.facingYawUpper mustEqual 0
                  b.lfs mustEqual false
                  b.grenade_state mustEqual GrenadeState.None
                  b.is_cloaking mustEqual false
                  b.unk5 mustEqual false
                  b.unk6 mustEqual false
                  b.charging_pose mustEqual false
                  b.unk7 mustEqual false
                  b.on_zipline.isEmpty mustEqual true

                  ribbons.upper mustEqual MeritCommendation.EmeraldVeteran
                  ribbons.middle mustEqual MeritCommendation.ScavengerTR1
                  ribbons.lower mustEqual MeritCommendation.BlackOpsParticipant
                  ribbons.tos mustEqual MeritCommendation.SixYearTR
                case _ =>
                  ko
              }

              (char.a.bep >= BattleRank.BR24.experience) mustEqual false
              char match {
                case DetailedCharacterData(a, b) =>
                  a.bep mustEqual 1784200L
                  a.cep mustEqual 53490L
                  a.unk1 mustEqual 0L
                  a.unk2 mustEqual 0L
                  a.unk3 mustEqual 0L
                  a.healthMax mustEqual 100
                  a.health mustEqual 100
                  a.unk4 mustEqual false
                  a.armor mustEqual 50
                  a.unk5 mustEqual 32831L
                  a.staminaMax mustEqual 100
                  a.stamina mustEqual 100
                  a.max_field.isEmpty mustEqual true
                  a.unk6 mustEqual 0
                  a.unk7 mustEqual 6
                  a.unk8 mustEqual 1184175L
                  a.unk9 mustEqual List(0, 0, 0, 0, 0, 0)
                  a.certs mustEqual List(
                    Certification.StandardAssault,
                    Certification.MediumAssault,
                    Certification.HeavyAssault,
                    Certification.AntiVehicular,
                    Certification.AirCavalryScout,
                    Certification.StandardExoSuit,
                    Certification.AgileExoSuit,
                    Certification.Medical,
                    Certification.AdvancedMedical,
                    Certification.Hacking,
                    Certification.AdvancedHacking,
                    Certification.Engineering
                  )

                  b.unk1.contains(21236) mustEqual true
                  b.implants mustEqual List(
                    ImplantEntry(ImplantType.Surge, Some(94), false),
                    ImplantEntry(ImplantType.Targeting, Some(91), false),
                    ImplantEntry(ImplantType.DarklightVision, Some(91), false)
                  )
                  b.unk2 mustEqual List()
                  b.unk3 mustEqual List()
                  b.firstTimeEvents.size mustEqual 209 //too many to bother listing; see encoding test
                  b.tutorials mustEqual List()
                  b.unk4 mustEqual 0L
                  b.unk5 mustEqual 0L
                  b.unk6 mustEqual 0L
                  b.unk7 mustEqual 0L
                  b.unk8 mustEqual 0L
                  b.imprinting.isEmpty mustEqual true
                  b.unkA mustEqual List(
                    9, 16, 17, 69, 107, 108, 114, 115, 134, 171, 178, 196, 199, 222, 229, 283, 297, 347, 360, 391, 399,
                    421
                  )
                  b.unkB mustEqual List()
                  b.unkC mustEqual false
                  b.cosmetics.isEmpty mustEqual true
                case _ =>
                  ko
              }

              inv.contents.length mustEqual 10
              //check first and last entries of inventory for accuracy
              inv.contents.head mustEqual InternalSlot(
                730,
                PlanetSideGUID(3465),
                0,
                DetailedWeaponData(
                  CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
                  0,
                  List(
                    InternalSlot(
                      28,
                      PlanetSideGUID(3722),
                      0,
                      DetailedAmmoBoxData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        20
                      )
                    )
                  ),
                  false
                )
              )
              //...
              inv.contents(9) mustEqual InternalSlot(
                728,
                PlanetSideGUID(4731),
                39,
                DetailedREKData(
                  CommonFieldData(
                    PlanetSideEmpire.TR,
                    false,
                    false,
                    true,
                    None,
                    false,
                    Some(false),
                    None,
                    PlanetSideGUID(0)
                  ),
                  16
                )
              )

              hand mustEqual DrawnSlot.None
            case _ =>
              ko
          }
        case _ =>
          ko
      }
    }

    "encode" in {
      val pos: PlacementData = PlacementData(
        3674.8438f, 2726.789f, 91.15625f, 0, 0, 36.5625f
      )
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "IlllIIIlllIlIllIlllIllI",
          PlanetSideEmpire.VS,
          CharacterSex.Female,
          41,
          CharacterVoice.Voice1
        ),
        CommonFieldData(
          PlanetSideEmpire.VS,
          false,
          false,
          true,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.Standard,
        0,
        41605313L,
        0,
        0,
        0,
        65535
      )
      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        0L,
        "",
        0,
        false,
        false,
        false,
        false,
        false,
        2.8125f,
        61.875f,
        true,
        GrenadeState.None,
        false,
        false,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars(
          MeritCommendation.None,
          MeritCommendation.None,
          MeritCommendation.None,
          MeritCommendation.None
        )
      )
      val ba: DetailedCharacterA = DetailedCharacterA(
        0L,
        0L,
        0L,
        0L,
        0L,
        100,
        100,
        false,
        50,
        32831L,
        100,
        100,
        None,
        0,
        0,
        0L,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.ATV,
          Certification.Harasser,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.ReinforcedExoSuit
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        None,
        Nil,
        Nil,
        Nil,
        List(
          "xpe_sanctuary_help",
          "xpe_th_firemodes",
          "used_beamer",
          "map13"
        ),
        Nil,
        0L,
        0L,
        0L,
        0L,
        0L,
        Some(ImprintingProgress(0, 0)),
        Nil,
        Nil,
        false,
        None
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv = InventoryData(
        List(
          InventoryItemData(
            ObjectClass.beamer,
            PlanetSideGUID(76),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16)))
            )
          ),
          InventoryItemData(
            ObjectClass.suppressor,
            PlanetSideGUID(78),
            2,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25)))
            )
          ),
          InventoryItemData(
            ObjectClass.forceblade,
            PlanetSideGUID(80),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1)))
            )
          ),
          InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(
            ObjectClass.remote_electronics_kit,
            PlanetSideGUID(88),
            39,
            DetailedREKData(
              CommonFieldData(
                PlanetSideEmpire.VS,
                false,
                false,
                true,
                None,
                false,
                Some(false),
                None,
                PlanetSideGUID(0)
              )
            )
          )
        )
      )
      val obj = DetailedPlayerData.apply(pos, app, char, inv, DrawnSlot.Pistol1)

      val msg      = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
      val pkt      = PacketCoding.encodePacket(msg).require.toByteVector
      val pkt_bitv = pkt.toBitVector
      val ori_bitv = string.toBitVector
      pkt_bitv.take(724) mustEqual ori_bitv.take(724) //skip 1; this is the highest bit of facingPitch
      pkt_bitv.drop(725) mustEqual ori_bitv.drop(725)
      //TODO work on DetailedCharacterData to make this pass as a single stream
    }

    "encode (character, seated)" in {
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "IlllIIIlllIlIllIlllIllI",
          PlanetSideEmpire.VS,
          CharacterSex.Female,
          41,
          CharacterVoice.Voice1
        ),
        CommonFieldData(
          PlanetSideEmpire.VS,
          false,
          false,
          false,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.Standard,
        0,
        192L,
        0,
        0,
        0,
        0
      )
      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        0L,
        "",
        0,
        false,
        false,
        false,
        false,
        false,
        5.625f,
        61.875f,
        true,
        GrenadeState.None,
        false,
        false,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars(
          MeritCommendation.None,
          MeritCommendation.None,
          MeritCommendation.None,
          MeritCommendation.None
        )
      )
      val ba: DetailedCharacterA = DetailedCharacterA(
        0L,
        0L,
        0L,
        0L,
        0L,
        100,
        100,
        false,
        50,
        32831L,
        100,
        100,
        None,
        0,
        0,
        0L,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.ATV,
          Certification.Harasser,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.ReinforcedExoSuit
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        None,
        Nil,
        Nil,
        Nil,
        List(
          "xpe_sanctuary_help",
          "xpe_th_firemodes",
          "used_beamer",
          "map13"
        ),
        Nil,
        0L,
        0L,
        0L,
        0L,
        0L,
        Some(ImprintingProgress(0, 0)),
        Nil,
        Nil,
        false,
        None
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv = InventoryData(
        List(
          InventoryItemData(
            ObjectClass.beamer,
            PlanetSideGUID(76),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16)))
            )
          ),
          InventoryItemData(
            ObjectClass.suppressor,
            PlanetSideGUID(78),
            2,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25)))
            )
          ),
          InventoryItemData(
            ObjectClass.forceblade,
            PlanetSideGUID(80),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1)))
            )
          ),
          InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)),
          InventoryItemData(
            ObjectClass.remote_electronics_kit,
            PlanetSideGUID(88),
            39,
            DetailedREKData(
              CommonFieldData(
                PlanetSideEmpire.VS,
                false,
                false,
                true,
                None,
                false,
                Some(false),
                None,
                PlanetSideGUID(0)
              )
            )
          )
        )
      )
      val obj = DetailedPlayerData.apply(app, char, inv, DrawnSlot.Pistol1)
      //it shouldn't be Pistol1 if he's seated but it's fine for the test

      val msg =
        ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), ObjectCreateMessageParent(PlanetSideGUID(43981), 0), obj)
      val pkt      = PacketCoding.encodePacket(msg).require.toByteVector
      val pkt_bitv = pkt.toBitVector
      val ori_bitv = string_seated.toBitVector
      pkt_bitv.take(668) mustEqual ori_bitv.take(668) //skip 1; this is the highest bit of facingPitch
      pkt_bitv.drop(670) mustEqual ori_bitv.drop(670)
      //TODO work on DetailedCharacterData to make this pass as a single stream
    }

    "encode (max)" in {
      val pos: PlacementData = PlacementData(
        Vector3(3990.7734f, 3656.5781f, 230.70312f),
        Vector3(0, 0, 67.5f),
        None
      )
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "HaHaATRMax",
          PlanetSideEmpire.TR,
          CharacterSex.Male,
          57,
          CharacterVoice.Voice1
        ),
        CommonFieldData(
          PlanetSideEmpire.TR,
          false,
          false,
          true,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.MAX,
        1,
        41605870L,
        0,
        0,
        0,
        65535
      )
      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        0L,
        "",
        0,
        false,
        false,
        false,
        false,
        false,
        -11.25f,
        0,
        true,
        GrenadeState.None,
        false,
        false,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars()
      )
      val ba: DetailedCharacterA = DetailedCharacterA(
        15301L,
        0L,
        0L,
        0L,
        0L,
        120,
        120,
        false,
        641,
        32831L,
        100,
        100,
        Some(0),
        0,
        0,
        0L,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.UniMAX
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        None,
        Nil,
        Nil,
        Nil,
        List(
          "xpe_battle_rank_3",
          "xpe_bind_facility",
          "xpe_instant_action",
          "xpe_battle_rank_4",
          "xpe_battle_rank_2",
          "xpe_sanctuary_help",
          "xpe_drop_pod",
          "xpe_orbital_shuttle",
          "xpe_battle_rank_5",
          "xpe_th_nonsanc",
          "xpe_th_ground_p",
          "xpe_th_ammo",
          "xpe_th_firemodes",
          "xpe_th_max",
          "visited_spitfire_turret",
          "visited_wall_turret",
          "visited_resource_silo",
          "visited_certification_terminal",
          "visited_med_terminal",
          "visited_broadcast_warpgate",
          "used_phalanx",
          "visited_air_vehicle_terminal",
          "visited_bfr_terminal",
          "used_cycler",
          "visited_galaxy_terminal",
          "visited_implant_terminal",
          "visited_external_door_lock",
          "visited_respawn_terminal",
          "visited_locker",
          "visited_motion_sensor",
          "used_grenade_plasma",
          "used_rek",
          "used_repeater",
          "visited_deconstruction_terminal",
          "visited_secondary_capture",
          "used_suppressor",
          "used_trhev_burster",
          "used_trhev_dualcycler",
          "used_trhev_pounder",
          "visited_capture_terminal",
          "visited_order_terminal",
          "visited_ground_vehicle_terminal",
          "map12",
          "map10",
          "map09",
          "map05",
          "map03",
          "map02"
        ),
        Nil,
        0L,
        0L,
        0L,
        0L,
        0L,
        Some(ImprintingProgress(0, 0)),
        Nil,
        Nil,
        false,
        None
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv = InventoryData(
        List(
          InternalSlot(
            889,
            PlanetSideGUID(2),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(
                InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8, 200)),
                InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8, 200)),
                InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8, 200))
              )
            )
          ),
          InternalSlot(
            175,
            PlanetSideGUID(6),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(
                InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8, 1))
              )
            )
          ),
          InternalSlot(
            456,
            PlanetSideGUID(8),
            5,
            DetailedLockerContainerData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              None
            )
          ),
          InternalSlot(265, PlanetSideGUID(9), 6, DetailedAmmoBoxData(8, 36)),
          InternalSlot(265, PlanetSideGUID(10), 10, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(11), 14, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(12), 18, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(13), 70, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(14), 74, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(15), 78, DetailedAmmoBoxData(8, 100)),
          InternalSlot(265, PlanetSideGUID(16), 82, DetailedAmmoBoxData(8, 100)),
          InternalSlot(536, PlanetSideGUID(17), 134, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(18), 138, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(19), 142, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(20), 146, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(21), 166, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(22), 170, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(23), 174, DetailedAmmoBoxData(8, 1)),
          InternalSlot(536, PlanetSideGUID(24), 178, DetailedAmmoBoxData(8, 1))
        )
      )
      val obj = DetailedPlayerData(pos, app, char, inv, DrawnSlot.Pistol1)

      val msg = ObjectCreateDetailedMessage(ObjectClass.avatar, PlanetSideGUID(1), obj)
      val pkt = PacketCoding.encodePacket(msg).require.toByteVector
      pkt mustEqual string_max
    }

    "encode (BR32)" in {
      val pos: PlacementData = PlacementData(
        Vector3(5500.0f, 3800.0f, 71.484375f),
        Vector3(0, 0, 90.0f),
        None
      )
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "KiCkJr",
          PlanetSideEmpire.NC,
          CharacterSex.Male,
          24,
          CharacterVoice.Voice4
        ),
        CommonFieldData(
          PlanetSideEmpire.NC,
          false,
          false,
          true,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.Agile,
        0,
        733931L,
        0,
        0,
        0,
        0
      )
      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        556539L,
        "",
        14,
        false,
        false,
        false,
        false,
        false,
        -11.25f,
        -11.25f,
        false,
        GrenadeState.None,
        false,
        true,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars(
          MeritCommendation.Loser4,
          MeritCommendation.EventNCElite,
          MeritCommendation.HeavyAssault6,
          MeritCommendation.SixYearNC
        )
      )
      val ba: DetailedCharacterA = DetailedCharacterA(
        6366766L,
        694787L,
        0L,
        0L,
        0L,
        100,
        100,
        false,
        100,
        32831L,
        100,
        46,
        None,
        0,
        4,
        3278759L,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.HeavyAssault,
          Certification.AntiVehicular,
          Certification.AirCavalryScout,
          Certification.GroundSupport,
          Certification.Harasser,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.Medical,
          Certification.AdvancedMedical,
          Certification.Hacking,
          Certification.AdvancedHacking,
          Certification.Engineering,
          Certification.CombatEngineering
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        None,
        List(
          ImplantEntry(ImplantType.AudioAmplifier, None),
          ImplantEntry(ImplantType.Targeting, None),
          ImplantEntry(ImplantType.Surge, None)
        ),
        Nil,
        Nil,
        List(
          "xpe_overhead_map",
          "xpe_warp_gate",
          "xpe_form_outfit",
          "xpe_blackops",
          "xpe_command_rank_5",
          "xpe_command_rank_3",
          "xpe_sanctuary_help",
          "xpe_battle_rank_13",
          "xpe_battle_rank_12",
          "xpe_battle_rank_10",
          "xpe_battle_rank_14",
          "xpe_battle_rank_15",
          "xpe_orbital_shuttle",
          "xpe_drop_pod",
          "xpe_bind_facility",
          "xpe_battle_rank_3",
          "xpe_battle_rank_5",
          "xpe_battle_rank_4",
          "xpe_join_squad",
          "xpe_form_squad",
          "xpe_instant_action",
          "xpe_battle_rank_2",
          "xpe_warp_gate_usage",
          "xpe_battle_rank_8",
          "xpe_battle_rank_11",
          "xpe_battle_rank_6",
          "xpe_mail_alert",
          "xpe_command_rank_1",
          "xpe_battle_rank_20",
          "xpe_battle_rank_18",
          "xpe_battle_rank_19",
          "xpe_join_platoon",
          "xpe_battle_rank_17",
          "xpe_battle_rank_16",
          "xpe_join_outfit",
          "xpe_battle_rank_25",
          "xpe_battle_rank_24",
          "xpe_command_rank_4",
          "xpe_form_platoon",
          "xpe_bind_ams",
          "xpe_battle_rank_9",
          "xpe_battle_rank_7",
          "xpe_th_router",
          "xpe_th_flail",
          "xpe_th_ant",
          "xpe_th_ams",
          "xpe_th_ground_p",
          "xpe_th_air_p",
          "xpe_th_hover",
          "xpe_th_ground",
          "xpe_th_bfr",
          "xpe_th_afterburner",
          "xpe_th_air",
          "xpe_th_cloak",
          "used_oicw",
          "used_advanced_ace",
          "visited_spitfire_turret",
          "visited_spitfire_cloaked",
          "visited_spitfire_aa",
          "visited_tank_traps",
          "visited_portable_manned_turret_nc",
          "visited_portable_manned_turret_tr",
          "used_magcutter",
          "used_chainblade",
          "used_forceblade",
          "visited_wall_turret",
          "visited_ancient_terminal",
          "visited_ams",
          "visited_ant",
          "visited_dropship",
          "visited_liberator",
          "visited_lightgunship",
          "visited_lightning",
          "visited_magrider",
          "visited_prowler",
          "visited_quadstealth",
          "visited_skyguard",
          "visited_threemanheavybuggy",
          "visited_two_man_assault_buggy",
          "visited_twomanheavybuggy",
          "visited_twomanhoverbuggy",
          "visited_vanguard",
          "visited_flail",
          "visited_router",
          "visited_switchblade",
          "visited_aurora",
          "visited_battlewagon",
          "visited_fury",
          "visited_quadassault",
          "visited_galaxy_gunship",
          "visited_apc_tr",
          "visited_apc_vs",
          "visited_lodestar",
          "visited_phantasm",
          "visited_thunderer",
          "visited_apc_nc",
          "visited_vulture",
          "visited_wasp",
          "visited_mosquito",
          "visited_aphelion_flight",
          "visited_aphelion_gunner",
          "visited_colossus_flight",
          "visited_colossus_gunner",
          "visited_peregrine_flight",
          "visited_peregrine_gunner",
          "used_bank",
          "visited_resource_silo",
          "visited_certification_terminal",
          "visited_med_terminal",
          "used_nano_dispenser",
          "visited_sensor_shield",
          "visited_broadcast_warpgate",
          "used_phalanx",
          "used_phalanx_avcombo",
          "used_phalanx_flakcombo",
          "visited_warpgate_small",
          "used_flamethrower",
          "used_ancient_turret_weapon",
          "visited_LLU_socket",
          "used_energy_gun_nc",
          "visited_mediumtransport",
          "used_aphelion_immolation_cannon",
          "used_grenade_plasma",
          "used_grenade_jammer",
          "visited_shield_generator",
          "visited_motion_sensor",
          "visited_health_crystal",
          "visited_repair_crystal",
          "visited_vehicle_crystal",
          "used_grenade_frag",
          "used_ace",
          "visited_adv_med_terminal",
          "used_beamer",
          "used_bolt_driver",
          "used_cycler",
          "used_gauss",
          "used_hunterseeker",
          "used_isp",
          "used_lancer",
          "used_lasher",
          "used_maelstrom",
          "used_phoenix",
          "used_pulsar",
          "used_punisher",
          "used_r_shotgun",
          "used_radiator",
          "used_rek",
          "used_repeater",
          "used_rocklet",
          "used_striker",
          "used_suppressor",
          "used_thumper",
          "visited_vanu_control_console",
          "visited_capture_terminal",
          "used_mini_chaingun",
          "used_laze_pointer",
          "used_telepad",
          "used_spiker",
          "used_heavy_sniper",
          "used_command_uplink",
          "used_firebird",
          "used_flechette",
          "used_heavy_rail_beam",
          "used_ilc9",
          "visited_generator_terminal",
          "visited_locker",
          "visited_external_door_lock",
          "visited_air_vehicle_terminal",
          "visited_galaxy_terminal",
          "visited_implant_terminal",
          "visited_secondary_capture",
          "used_25mm_cannon",
          "used_liberator_bombardier",
          "visited_repair_silo",
          "visited_vanu_module",
          "used_flail_weapon",
          "used_scythe",
          "visited_respawn_terminal",
          "used_ballgun",
          "used_energy_gun_tr",
          "used_anniversary_guna",
          "used_anniversary_gunb",
          "used_anniversary_gun",
          "used_75mm_cannon",
          "used_apc_nc_weapon",
          "used_apc_tr_weapon",
          "used_apc_vs_weapon",
          "used_flux_cannon",
          "used_aphelion_plasma_rocket_pod",
          "used_aphelion_ppa",
          "used_fluxpod",
          "visited_bfr_terminal",
          "used_colossus_cluster_bomb_pod",
          "used_colossus_dual_100mm_cannons",
          "used_colossus_tank_cannon",
          "visited_energy_crystal",
          "used_heavy_grenade_launcher",
          "used_35mm_rotarychaingun",
          "used_katana",
          "used_35mm_cannon",
          "used_reaver_weapons",
          "used_lightning_weapons",
          "used_med_app",
          "used_20mm_cannon",
          "visited_monolith_amerish",
          "visited_monolith_ceryshen",
          "visited_monolith_cyssor",
          "visited_monolith_esamir",
          "visited_monolith_forseral",
          "visited_monolith_ishundar",
          "visited_monolith_searhus",
          "visited_monolith_solsar",
          "used_nc_hev_falcon",
          "used_nc_hev_scattercannon",
          "used_nc_hev_sparrow",
          "used_armor_siphon",
          "used_peregrine_dual_machine_gun",
          "used_peregrine_dual_rocket_pods",
          "used_peregrine_mechhammer",
          "used_peregrine_particle_cannon",
          "used_peregrine_sparrow",
          "used_105mm_cannon",
          "used_15mm_chaingun",
          "used_pulsed_particle_accelerator",
          "used_rotarychaingun",
          "visited_deconstruction_terminal",
          "used_skyguard_weapons",
          "visited_generator",
          "used_gauss_cannon",
          "used_trek",
          "used_vanguard_weapons",
          "visited_ancient_air_vehicle_terminal",
          "visited_ancient_equipment_terminal",
          "visited_order_terminal",
          "visited_ancient_ground_vehicle_terminal",
          "visited_ground_vehicle_terminal",
          "used_vulture_bombardier",
          "used_vulture_nose_cannon",
          "used_vulture_tail_cannon",
          "used_wasp_weapon_system",
          "visited_charlie01",
          "visited_charlie02",
          "visited_charlie03",
          "visited_charlie04",
          "visited_charlie05",
          "visited_charlie06",
          "visited_charlie07",
          "visited_charlie08",
          "visited_charlie09",
          "visited_gingerman_atar",
          "visited_gingerman_dahaka",
          "visited_gingerman_hvar",
          "visited_gingerman_izha",
          "visited_gingerman_jamshid",
          "visited_gingerman_mithra",
          "visited_gingerman_rashnu",
          "visited_gingerman_sraosha",
          "visited_gingerman_yazata",
          "visited_gingerman_zal",
          "visited_sled01",
          "visited_sled02",
          "visited_sled04",
          "visited_sled05",
          "visited_sled06",
          "visited_sled07",
          "visited_sled08",
          "visited_snowman_amerish",
          "visited_snowman_ceryshen",
          "visited_snowman_cyssor",
          "visited_snowman_esamir",
          "visited_snowman_forseral",
          "visited_snowman_hossin",
          "visited_snowman_ishundar",
          "visited_snowman_searhus",
          "visited_snowman_solsar",
          "ugd06",
          "ugd05",
          "ugd04",
          "ugd03",
          "ugd02",
          "ugd01",
          "map99",
          "map98",
          "map97",
          "map96",
          "map15",
          "map14",
          "map11",
          "map08",
          "map04",
          "map05",
          "map03",
          "map01",
          "map06",
          "map02",
          "map09",
          "map07",
          "map10"
        ),
        List(
          "training_start_nc",
          "training_ui",
          "training_map"
        ),
        0L,
        0L,
        0L,
        0L,
        0L,
        None,
        Nil,
        Nil,
        false,
        Some(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv = InventoryData(
        List(
          InternalSlot(
            531,
            PlanetSideGUID(4202),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(389, PlanetSideGUID(3942), 0, DetailedAmmoBoxData(8, 100)))
            )
          ),
          InternalSlot(
            132,
            PlanetSideGUID(6924),
            1,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(111, PlanetSideGUID(9157), 0, DetailedAmmoBoxData(8, 100)))
            )
          ),
          InternalSlot(
            714,
            PlanetSideGUID(8498),
            2,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(755, PlanetSideGUID(5356), 0, DetailedAmmoBoxData(8, 16)))
            )
          ),
          InternalSlot(
            468,
            PlanetSideGUID(7198),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(540, PlanetSideGUID(5009), 0, DetailedAmmoBoxData(8, 1)))
            )
          ),
          InternalSlot(
            456,
            PlanetSideGUID(5374),
            5,
            DetailedLockerContainerData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              Some(
                InventoryData(
                  List(
                    InternalSlot(
                      429,
                      PlanetSideGUID(3021),
                      0,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(272, PlanetSideGUID(8729), 0, DetailedAmmoBoxData(8, 0)))
                      )
                    ),
                    InternalSlot(
                      838,
                      PlanetSideGUID(8467),
                      9,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(839, PlanetSideGUID(8603), 0, DetailedAmmoBoxData(8, 5)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(3266), 18, DetailedAmmoBoxData(8, 27)),
                    InternalSlot(
                      577,
                      PlanetSideGUID(2934),
                      22,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(111, PlanetSideGUID(4682), 0, DetailedAmmoBoxData(8, 100)))
                      )
                    ),
                    InternalSlot(839, PlanetSideGUID(3271), 90, DetailedAmmoBoxData(8, 15)),
                    InternalSlot(839, PlanetSideGUID(7174), 94, DetailedAmmoBoxData(8, 6)),
                    InternalSlot(
                      429,
                      PlanetSideGUID(6084),
                      98,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(272, PlanetSideGUID(5928), 0, DetailedAmmoBoxData(8, 35)))
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(5000),
                      108,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(6277), 0, DetailedAmmoBoxData(8, 150)))
                      )
                    ),
                    InternalSlot(
                      429,
                      PlanetSideGUID(4341),
                      189,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(272, PlanetSideGUID(7043), 0, DetailedAmmoBoxData(8, 35)))
                      )
                    ),
                    InternalSlot(
                      556,
                      PlanetSideGUID(4168),
                      198,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(8937), 0, DetailedAmmoBoxData(8, 100)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(3173), 207, DetailedAmmoBoxData(8, 50)),
                    InternalSlot(
                      462,
                      PlanetSideGUID(3221),
                      210,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(4031), 0, DetailedAmmoBoxData(8, 150)))
                      )
                    ),
                    InternalSlot(
                      556,
                      PlanetSideGUID(6853),
                      280,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(29, PlanetSideGUID(8524), 0, DetailedAmmoBoxData(8, 67)))
                      )
                    ),
                    InternalSlot(
                      556,
                      PlanetSideGUID(4569),
                      290,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(5584), 0, DetailedAmmoBoxData(8, 100)))
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(9294),
                      300,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(3118), 0, DetailedAmmoBoxData(8, 150)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(4759), 387, DetailedAmmoBoxData(8, 50)),
                    InternalSlot(
                      462,
                      PlanetSideGUID(7377),
                      390,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(8155), 0, DetailedAmmoBoxData(8, 150)))
                      )
                    ),
                    InternalSlot(843, PlanetSideGUID(6709), 480, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(843, PlanetSideGUID(5276), 484, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(843, PlanetSideGUID(7769), 488, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(844, PlanetSideGUID(5334), 492, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(844, PlanetSideGUID(6219), 496, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(842, PlanetSideGUID(7279), 500, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(842, PlanetSideGUID(5415), 504, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(
                      175,
                      PlanetSideGUID(5741),
                      540,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(5183), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(6208),
                      541,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(5029), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(8589),
                      542,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(9217), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(8901),
                      543,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7633), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(8419),
                      544,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6546), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(4715),
                      545,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(8453), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(3577),
                      546,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(9202), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(6003),
                      547,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(3260), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(9140),
                      548,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(3815), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(4913),
                      549,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7222), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(6954),
                      550,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(2953), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(6405),
                      551,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4676), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(8915),
                      552,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4018), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(4993),
                      553,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6775), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(5053),
                      554,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6418), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(9244),
                      555,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(3327), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(6292),
                      556,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6918), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(842, PlanetSideGUID(5357), 558, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(844, PlanetSideGUID(4435), 562, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(843, PlanetSideGUID(7242), 566, DetailedAmmoBoxData(8, 1)),
                    InternalSlot(
                      175,
                      PlanetSideGUID(7330),
                      570,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4786), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(7415),
                      571,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6536), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(3949),
                      572,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7526), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(3805),
                      573,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7358), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(4493),
                      574,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6852), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(5762),
                      575,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(3463), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(3315),
                      576,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7619), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(6263),
                      577,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(5912), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(4028),
                      578,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(8021), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(2843),
                      579,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7250), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(9143),
                      580,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(5195), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(5024),
                      581,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4287), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(6582),
                      582,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4915), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(6425),
                      583,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(8872), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      468,
                      PlanetSideGUID(4431),
                      584,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(4191), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(8339),
                      585,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(7317), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    ),
                    InternalSlot(
                      175,
                      PlanetSideGUID(3277),
                      586,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          true,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(540, PlanetSideGUID(6469), 0, DetailedAmmoBoxData(8, 1)))
                      )
                    )
                  )
                )
              )
            )
          ),
          InternalSlot(
            213,
            PlanetSideGUID(6877),
            6,
            DetailedCommandDetonaterData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
            )
          ),
          InternalSlot(755, PlanetSideGUID(6227), 9, DetailedAmmoBoxData(8, 16)),
          InternalSlot(
            728,
            PlanetSideGUID(7181),
            12,
            DetailedREKData(
              CommonFieldData(
                PlanetSideEmpire.NC,
                false,
                false,
                true,
                None,
                false,
                Some(false),
                None,
                PlanetSideGUID(0)
              ),
              16
            )
          ),
          InternalSlot(536, PlanetSideGUID(4077), 33, DetailedAmmoBoxData(8, 1)),
          InternalSlot(
            680,
            PlanetSideGUID(4377),
            37,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(681, PlanetSideGUID(8905), 0, DetailedAmmoBoxData(8, 3)))
            )
          ),
          InternalSlot(
            32,
            PlanetSideGUID(5523),
            39,
            DetailedConstructionToolData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
            )
          ),
          InternalSlot(
            673,
            PlanetSideGUID(3661),
            60,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(674, PlanetSideGUID(8542), 0, DetailedAmmoBoxData(8, 3)))
            )
          )
        )
      )
      val obj = DetailedPlayerData(pos, app, char, inv, DrawnSlot.None)

      val msg = ObjectCreateDetailedMessage(ObjectClass.avatar, PlanetSideGUID(75), obj)
      val pkt = PacketCoding.encodePacket(msg).require.toByteVector
      pkt mustEqual string_br32
    }

    "encode (ccrider)" in {
      val pos: PlacementData = PlacementData(
        Vector3(2931.5f, 4404.6953f, 45.0625f),
        Vector3.z(36.5625f),
        None
      )
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "CCRIDER",
          PlanetSideEmpire.NC,
          CharacterSex.Male,
          20,
          CharacterVoice.Voice3
        ),
        CommonFieldData(
          PlanetSideEmpire.NC,
          false,
          false,
          false,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.Standard,
        0,
        1176612L,
        15,
        5,
        10,
        1
      )
      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        25044L,
        "Black Armored Reapers",
        15,
        false,
        false,
        false,
        false,
        false,
        0,
        0,
        false,
        GrenadeState.None,
        false,
        false,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars(
          MeritCommendation.DefenseNC5,
          MeritCommendation.HackingSupport5,
          MeritCommendation.BFRAdvanced2,
          MeritCommendation.SixYearNC
        )
      )
      val ba: DetailedCharacterA = DetailedCharacterA(
        6571522L,
        659329L,
        0L,
        0L,
        0L,
        100,
        100,
        false,
        50,
        32831,
        100,
        100,
        None,
        0,
        6,
        3165669,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.HeavyAssault,
          Certification.AirCavalryScout,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.UniMAX,
          Certification.Medical,
          Certification.AdvancedMedical,
          Certification.Hacking,
          Certification.AdvancedHacking,
          Certification.ExpertHacking,
          Certification.Engineering
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        Some(14140),
        List(
          ImplantEntry(ImplantType.Surge, Some(94), false),
          ImplantEntry(ImplantType.DarklightVision, Some(91), false),
          ImplantEntry(ImplantType.Targeting, Some(91), false)
        ),
        List(),
        List(),
        List(
          "xpe_blackops",
          "xpe_battle_rank_9",
          "xpe_battle_rank_23",
          "xpe_command_rank_1",
          "xpe_form_outfit",
          "xpe_mail_alert",
          "xpe_battle_rank_22",
          "xpe_command_rank_3",
          "xpe_form_platoon",
          "xpe_battle_rank_13",
          "xpe_battle_rank_12",
          "xpe_battle_rank_10",
          "xpe_battle_rank_14",
          "xpe_battle_rank_15",
          "xpe_battle_rank_8",
          "xpe_battle_rank_11",
          "xpe_battle_rank_21",
          "xpe_battle_rank_20",
          "xpe_battle_rank_18",
          "xpe_battle_rank_19",
          "xpe_join_platoon",
          "xpe_battle_rank_17",
          "xpe_battle_rank_16",
          "xpe_join_outfit",
          "xpe_battle_rank_25",
          "xpe_battle_rank_24",
          "xpe_battle_rank_7",
          "xpe_bind_facility",
          "xpe_bind_ams",
          "xpe_command_rank_5",
          "xpe_command_rank_2",
          "xpe_instant_action",
          "xpe_form_squad",
          "xpe_battle_rank_4",
          "xpe_warp_gate_usage",
          "xpe_battle_rank_2",
          "xpe_battle_rank_3",
          "xpe_sanctuary_help",
          "xpe_drop_pod",
          "xpe_orbital_shuttle",
          "xpe_battle_rank_6",
          "xpe_join_squad",
          "xpe_battle_rank_5",
          "xpe_th_switchblade",
          "xpe_th_router",
          "xpe_th_flail",
          "xpe_th_ant",
          "xpe_th_ams",
          "xpe_th_bfr",
          "used_oicw",
          "used_advanced_ace",
          "visited_spitfire_turret",
          "visited_spitfire_cloaked",
          "visited_spitfire_aa",
          "visited_tank_traps",
          "visited_portable_manned_turret_nc",
          "used_magcutter",
          "visited_wall_turret",
          "visited_ams",
          "visited_ant",
          "visited_dropship",
          "visited_liberator",
          "visited_lightgunship",
          "visited_lightning",
          "visited_magrider",
          "visited_prowler",
          "visited_quadstealth",
          "visited_skyguard",
          "visited_threemanheavybuggy",
          "visited_two_man_assault_buggy",
          "visited_twomanheavybuggy",
          "visited_twomanhoverbuggy",
          "visited_vanguard",
          "visited_flail",
          "visited_router",
          "visited_switchblade",
          "visited_aurora",
          "visited_battlewagon",
          "visited_fury",
          "visited_quadassault",
          "visited_galaxy_gunship",
          "visited_apc_tr",
          "visited_apc_vs",
          "visited_lodestar",
          "visited_phantasm",
          "visited_thunderer",
          "visited_apc_nc",
          "visited_vulture",
          "visited_wasp",
          "visited_mosquito",
          "visited_aphelion_flight",
          "visited_aphelion_gunner",
          "visited_colossus_flight",
          "visited_colossus_gunner",
          "visited_peregrine_flight",
          "visited_peregrine_gunner",
          "used_bank",
          "visited_resource_silo",
          "visited_certification_terminal",
          "visited_med_terminal",
          "used_nano_dispenser",
          "visited_sensor_shield",
          "visited_broadcast_warpgate",
          "used_phalanx",
          "used_phalanx_avcombo",
          "used_phalanx_flakcombo",
          "visited_warpgate_small",
          "used_flamethrower",
          "used_ancient_turret_weapon",
          "visited_LLU_socket",
          "used_energy_gun_nc",
          "visited_mediumtransport",
          "used_aphelion_immolation_cannon",
          "used_grenade_plasma",
          "used_grenade_jammer",
          "visited_shield_generator",
          "visited_motion_sensor",
          "visited_health_crystal",
          "visited_repair_crystal",
          "visited_vehicle_crystal",
          "used_grenade_frag",
          "used_ace",
          "visited_adv_med_terminal",
          "used_beamer",
          "used_bolt_driver",
          "used_cycler",
          "used_gauss",
          "used_hunterseeker",
          "used_isp",
          "used_lancer",
          "used_lasher",
          "used_maelstrom",
          "used_phoenix",
          "used_pulsar",
          "used_punisher",
          "used_r_shotgun",
          "used_radiator",
          "used_rek",
          "used_repeater",
          "used_rocklet",
          "used_striker",
          "used_suppressor",
          "used_thumper",
          "visited_vanu_control_console",
          "visited_capture_terminal",
          "used_mini_chaingun",
          "used_laze_pointer",
          "used_telepad",
          "used_spiker",
          "used_heavy_sniper",
          "used_command_uplink",
          "used_firebird",
          "used_flechette",
          "used_heavy_rail_beam",
          "used_ilc9",
          "visited_generator_terminal",
          "visited_locker",
          "visited_external_door_lock",
          "visited_air_vehicle_terminal",
          "visited_galaxy_terminal",
          "visited_implant_terminal",
          "visited_secondary_capture",
          "used_25mm_cannon",
          "used_liberator_bombardier",
          "visited_repair_silo",
          "visited_vanu_module",
          "used_flail_weapon",
          "used_scythe",
          "visited_respawn_terminal",
          "used_ballgun",
          "used_anniversary_guna",
          "used_anniversary_gunb",
          "used_anniversary_gun",
          "used_75mm_cannon",
          "used_apc_nc_weapon",
          "used_apc_tr_weapon",
          "used_apc_vs_weapon",
          "used_flux_cannon",
          "used_aphelion_laser",
          "used_aphelion_plasma_rocket_pod",
          "used_aphelion_ppa",
          "used_aphelion_starfire",
          "used_fluxpod",
          "visited_bfr_terminal",
          "used_colossus_burster",
          "used_colossus_chaingun",
          "used_colossus_cluster_bomb_pod",
          "used_colossus_dual_100mm_cannons",
          "used_colossus_tank_cannon",
          "visited_damage_crystal",
          "visited_energy_crystal",
          "used_heavy_grenade_launcher",
          "used_35mm_rotarychaingun",
          "used_katana",
          "used_35mm_cannon",
          "used_reaver_weapons",
          "used_lightning_weapons",
          "used_med_app",
          "used_20mm_cannon",
          "visited_monolith_amerish",
          "visited_monolith_ceryshen",
          "visited_monolith_cyssor",
          "visited_monolith_esamir",
          "visited_monolith_forseral",
          "visited_monolith_hossin",
          "visited_monolith_ishundar",
          "visited_monolith_searhus",
          "visited_monolith_solsar",
          "used_nc_hev_falcon",
          "used_nc_hev_scattercannon",
          "used_nc_hev_sparrow",
          "used_armor_siphon",
          "used_peregrine_dual_machine_gun",
          "used_peregrine_dual_rocket_pods",
          "used_peregrine_mechhammer",
          "used_ntu_siphon",
          "used_peregrine_particle_cannon",
          "used_peregrine_sparrow",
          "used_105mm_cannon",
          "used_15mm_chaingun",
          "used_pulsed_particle_accelerator",
          "used_rotarychaingun",
          "visited_deconstruction_terminal",
          "used_skyguard_weapons",
          "visited_generator",
          "used_gauss_cannon",
          "used_trek",
          "used_vanguard_weapons",
          "visited_ancient_air_vehicle_terminal",
          "visited_ancient_equipment_terminal",
          "visited_order_terminal",
          "visited_ancient_ground_vehicle_terminal",
          "visited_ground_vehicle_terminal",
          "used_vulture_bombardier",
          "used_vulture_nose_cannon",
          "used_vulture_tail_cannon",
          "used_wasp_weapon_system",
          "visited_charlie05",
          "visited_charlie06",
          "visited_charlie07",
          "visited_charlie08",
          "visited_charlie09",
          "visited_sled04",
          "visited_sled05",
          "visited_sled06",
          "visited_sled07",
          "visited_sled08",
          "ugd06",
          "ugd05",
          "ugd04",
          "ugd03",
          "ugd02",
          "ugd01",
          "map99",
          "map98",
          "map97",
          "map96",
          "map15",
          "map14",
          "map13",
          "map12",
          "map11",
          "map04",
          "map05",
          "map03",
          "map01",
          "map06",
          "map02",
          "map09",
          "map07",
          "map10"
        ),
        List(
          "training_weapons01",
          "training_warpgates",
          "training_map",
          "training_inventory",
          "training_healing",
          "training_hart",
          "training_armors",
          "training_welcome"
        ),
        0,
        0,
        0,
        0,
        0,
        None,
        List(
          9, 10, 11, 16, 17, 18, 30, 31, 32, 37, 38, 52, 53, 57, 69, 92, 99, 100, 107, 108, 109, 110, 114, 115, 116,
          117, 118, 127, 128, 129, 130, 131, 156, 163, 171, 178, 179, 180, 181, 194, 195, 198, 201, 215, 216, 217, 222,
          223, 224, 225, 226, 227, 229, 230, 243, 244, 257, 265, 266, 277, 278, 283, 284, 285, 286, 289, 290, 296, 313,
          334, 341, 342, 359, 369, 376, 377, 384, 391, 392, 393, 394, 398, 408, 415, 420, 424
        ),
        List(),
        false,
        Some(Set(Cosmetic.NoHelmet, Cosmetic.Sunglasses, Cosmetic.Earpiece, Cosmetic.BrimmedCap))
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv: InventoryData = InventoryData(
        List(
          InternalSlot(
            411,
            PlanetSideGUID(10022),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(755, PlanetSideGUID(10023), 0, DetailedAmmoBoxData(8, 8)))
            )
          ),
          InternalSlot(
            845,
            PlanetSideGUID(5671),
            2,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(28, PlanetSideGUID(10019), 0, DetailedAmmoBoxData(8, 25)))
            )
          ),
          InternalSlot(
            468,
            PlanetSideGUID(3754),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(InternalSlot(540, PlanetSideGUID(6693), 0, DetailedAmmoBoxData(8, 1)))
            )
          ),
          InternalSlot(
            456,
            PlanetSideGUID(8199),
            5,
            DetailedLockerContainerData(
              CommonFieldData(
                PlanetSideEmpire.NEUTRAL,
                false,
                false,
                false,
                None,
                false,
                None,
                None,
                PlanetSideGUID(0)
              ),
              Some(
                InventoryData(
                  List(
                    InternalSlot(
                      233,
                      PlanetSideGUID(6315),
                      0,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(6795), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(
                      233,
                      PlanetSideGUID(4302),
                      6,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(5511), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(
                      233,
                      PlanetSideGUID(6342),
                      12,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(7788), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(
                      233,
                      PlanetSideGUID(7392),
                      18,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(8335), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(
                      233,
                      PlanetSideGUID(4432),
                      24,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(7020), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(
                      716,
                      PlanetSideGUID(4219),
                      90,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(9275), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      716,
                      PlanetSideGUID(3869),
                      96,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(6099), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      716,
                      PlanetSideGUID(8954),
                      102,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(5972), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      233,
                      PlanetSideGUID(7476),
                      108,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(5704), 0, DetailedAmmoBoxData(0, 50)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(8800), 114, DetailedAmmoBoxData(0, 50)),
                    InternalSlot(272, PlanetSideGUID(8649), 177, DetailedAmmoBoxData(0, 50)),
                    InternalSlot(
                      716,
                      PlanetSideGUID(7580),
                      180,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(6734), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      716,
                      PlanetSideGUID(6464),
                      186,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(4738), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      716,
                      PlanetSideGUID(5408),
                      192,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(50, PlanetSideGUID(3579), 0, DetailedAmmoBoxData(0, 25)))
                      )
                    ),
                    InternalSlot(
                      556,
                      PlanetSideGUID(8957),
                      198,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(8223), 0, DetailedAmmoBoxData(0, 100)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(3928), 267, DetailedAmmoBoxData(0, 50)),
                    InternalSlot(
                      577,
                      PlanetSideGUID(3403),
                      279,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(111, PlanetSideGUID(4352), 0, DetailedAmmoBoxData(0, 100)))
                      )
                    ),
                    InternalSlot(
                      577,
                      PlanetSideGUID(8454),
                      285,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(111, PlanetSideGUID(8724), 0, DetailedAmmoBoxData(0, 100)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(3397), 357, DetailedAmmoBoxData(0, 50)),
                    InternalSlot(
                      429,
                      PlanetSideGUID(6695),
                      378,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(272, PlanetSideGUID(6842), 0, DetailedAmmoBoxData(0, 35)))
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(8304),
                      420,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(7089), 0, DetailedAmmoBoxData(0, 150)))
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(3346),
                      429,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(7557), 0, DetailedAmmoBoxData(0, 150)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(7515), 447, DetailedAmmoBoxData(0, 50)),
                    InternalSlot(
                      462,
                      PlanetSideGUID(4622),
                      510,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(6996), 0, DetailedAmmoBoxData(0, 150)))
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(6586),
                      519,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(463, PlanetSideGUID(6870), 0, DetailedAmmoBoxData(0, 150)))
                      )
                    ),
                    InternalSlot(
                      556,
                      PlanetSideGUID(4806),
                      528,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(InternalSlot(28, PlanetSideGUID(8798), 0, DetailedAmmoBoxData(0, 100)))
                      )
                    ),
                    InternalSlot(272, PlanetSideGUID(8429), 537, DetailedAmmoBoxData(0, 50))
                  )
                )
              )
            )
          ),
          InternalSlot(28, PlanetSideGUID(10018), 6, DetailedAmmoBoxData(8, 50)),
          InternalSlot(28, PlanetSideGUID(5612), 9, DetailedAmmoBoxData(8, 50)),
          InternalSlot(28, PlanetSideGUID(5128), 12, DetailedAmmoBoxData(8, 50)),
          InternalSlot(29, PlanetSideGUID(8363), 33, DetailedAmmoBoxData(8, 50)),
          InternalSlot(755, PlanetSideGUID(4090), 36, DetailedAmmoBoxData(8, 16)),
          InternalSlot(
            728,
            PlanetSideGUID(10075),
            39,
            DetailedREKData(
              CommonFieldData(
                PlanetSideEmpire.NC,
                false,
                false,
                true,
                None,
                false,
                Some(false),
                None,
                PlanetSideGUID(0)
              ),
              24
            )
          )
        )
      )
      val obj = DetailedPlayerData.apply(pos, app, char, inv, DrawnSlot.None)

      val msg = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
      val pkt = PacketCoding.encodePacket(msg).require.toByteVector
      pkt mustEqual string_ccrider
    }

    "encode (xRider912)" in {
      val pos: PlacementData = PlacementData(
        Vector3(3577.1797f, 2712.25f, 35.78125f),
        Vector3.z(50.625f),
        None
      )
      val aa: Int => CharacterAppearanceA = CharacterAppearanceA(
        BasicCharacterData(
          "xRider912",
          PlanetSideEmpire.TR,
          CharacterSex.Male,
          4,
          CharacterVoice.Voice1
        ),
        CommonFieldData(
          PlanetSideEmpire.TR,
          false,
          false,
          false,
          None,
          false,
          None,
          None,
          PlanetSideGUID(0)
        ),
        ExoSuitType.Standard,
        0,
        1267466L,
        3,
        3,
        0,
        0
      )

      val ab: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
        16507L,
        "Hooked On Insanity",
        5,
        false,
        false,
        false,
        false,
        false,
        0,
        0,
        false,
        GrenadeState.None,
        false,
        false,
        false,
        false,
        false,
        None
      )

      val app: Int => CharacterAppearanceData = CharacterAppearanceData(
        aa,
        ab,
        RibbonBars(
          MeritCommendation.EmeraldVeteran,
          MeritCommendation.ScavengerTR1,
          MeritCommendation.BlackOpsParticipant,
          MeritCommendation.SixYearTR
        )
      )

      val ba: DetailedCharacterA = DetailedCharacterA(
        1784200L,
        53490L,
        0L,
        0L,
        0L,
        100,
        100,
        false,
        50,
        32831,
        100,
        100,
        None,
        0,
        6,
        1184175,
        List(0, 0, 0, 0, 0, 0),
        List(
          Certification.StandardAssault,
          Certification.MediumAssault,
          Certification.HeavyAssault,
          Certification.AntiVehicular,
          Certification.AirCavalryScout,
          Certification.StandardExoSuit,
          Certification.AgileExoSuit,
          Certification.Medical,
          Certification.AdvancedMedical,
          Certification.Hacking,
          Certification.AdvancedHacking,
          Certification.Engineering
        )
      )
      val bb: (Long, Option[Int]) => DetailedCharacterB = DetailedCharacterB(
        Some(21236),
        List(
          ImplantEntry(ImplantType.Surge, Some(94), false),
          ImplantEntry(ImplantType.Targeting, Some(91), false),
          ImplantEntry(ImplantType.DarklightVision, Some(91), false)
        ),
        List(),
        List(),
        List(
          "xpe_command_rank_2",
          "xpe_join_platoon",
          "xpe_battle_rank_20",
          "xpe_battle_rank_21",
          "xpe_battle_rank_22",
          "xpe_form_outfit",
          "xpe_blackops",
          "xpe_battle_rank_13",
          "xpe_battle_rank_12",
          "xpe_battle_rank_10",
          "xpe_battle_rank_14",
          "xpe_battle_rank_15",
          "xpe_battle_rank_5",
          "xpe_join_squad",
          "xpe_form_squad",
          "xpe_instant_action",
          "xpe_battle_rank_8",
          "xpe_battle_rank_11",
          "xpe_battle_rank_6",
          "xpe_battle_rank_18",
          "xpe_battle_rank_19",
          "xpe_battle_rank_17",
          "xpe_battle_rank_16",
          "xpe_join_outfit",
          "xpe_battle_rank_9",
          "xpe_battle_rank_7",
          "xpe_command_rank_1",
          "xpe_orbital_shuttle",
          "xpe_drop_pod",
          "xpe_sanctuary_help",
          "xpe_bind_facility",
          "xpe_battle_rank_3",
          "xpe_battle_rank_2",
          "xpe_warp_gate_usage",
          "xpe_bind_ams",
          "xpe_battle_rank_4",
          "xpe_th_nonsanc",
          "xpe_th_router",
          "xpe_th_flail",
          "xpe_th_ant",
          "xpe_th_ams",
          "xpe_th_ground_p",
          "xpe_th_air_p",
          "xpe_th_hover",
          "xpe_th_ground",
          "xpe_th_bfr",
          "xpe_th_afterburner",
          "xpe_th_air",
          "xpe_th_ammo",
          "xpe_th_firemodes",
          "xpe_th_cloak",
          "xpe_th_max",
          "used_oicw",
          "used_advanced_ace",
          "visited_spitfire_turret",
          "visited_spitfire_cloaked",
          "visited_spitfire_aa",
          "visited_tank_traps",
          "visited_portable_manned_turret_tr",
          "used_chainblade",
          "visited_wall_turret",
          "visited_ams",
          "visited_ant",
          "visited_dropship",
          "visited_liberator",
          "visited_lightgunship",
          "visited_lightning",
          "visited_prowler",
          "visited_quadstealth",
          "visited_skyguard",
          "visited_threemanheavybuggy",
          "visited_two_man_assault_buggy",
          "visited_twomanheavybuggy",
          "visited_twomanhoverbuggy",
          "visited_vanguard",
          "visited_flail",
          "visited_router",
          "visited_battlewagon",
          "visited_fury",
          "visited_quadassault",
          "visited_galaxy_gunship",
          "visited_apc_tr",
          "visited_lodestar",
          "visited_phantasm",
          "visited_apc_nc",
          "visited_vulture",
          "visited_wasp",
          "visited_mosquito",
          "visited_colossus_flight",
          "used_bank",
          "visited_resource_silo",
          "visited_certification_terminal",
          "visited_med_terminal",
          "used_nano_dispenser",
          "visited_sensor_shield",
          "visited_broadcast_warpgate",
          "used_phalanx",
          "used_phalanx_flakcombo",
          "visited_warpgate_small",
          "used_flamethrower",
          "used_ancient_turret_weapon",
          "visited_LLU_socket",
          "visited_mediumtransport",
          "used_grenade_plasma",
          "used_grenade_jammer",
          "visited_shield_generator",
          "visited_motion_sensor",
          "visited_vehicle_crystal",
          "used_grenade_frag",
          "used_ace",
          "visited_adv_med_terminal",
          "used_bolt_driver",
          "used_cycler",
          "used_gauss",
          "used_hunterseeker",
          "used_isp",
          "used_lancer",
          "used_lasher",
          "used_maelstrom",
          "used_phoenix",
          "used_pulsar",
          "used_punisher",
          "used_r_shotgun",
          "used_radiator",
          "used_rek",
          "used_repeater",
          "used_rocklet",
          "used_striker",
          "used_suppressor",
          "used_thumper",
          "used_trhev_burster",
          "used_trhev_dualcycler",
          "used_trhev_pounder",
          "visited_vanu_control_console",
          "visited_capture_terminal",
          "used_mini_chaingun",
          "used_laze_pointer",
          "used_telepad",
          "used_spiker",
          "used_heavy_sniper",
          "used_firebird",
          "used_flechette",
          "used_heavy_rail_beam",
          "visited_generator_terminal",
          "visited_locker",
          "visited_external_door_lock",
          "visited_air_vehicle_terminal",
          "visited_galaxy_terminal",
          "visited_implant_terminal",
          "visited_secondary_capture",
          "used_25mm_cannon",
          "used_liberator_bombardier",
          "visited_repair_silo",
          "visited_vanu_module",
          "used_flail_weapon",
          "visited_respawn_terminal",
          "used_energy_gun_tr",
          "used_anniversary_guna",
          "used_anniversary_gunb",
          "used_apc_tr_weapon",
          "used_flux_cannon",
          "visited_bfr_terminal",
          "used_colossus_dual_100mm_cannons",
          "used_colossus_tank_cannon",
          "used_heavy_grenade_launcher",
          "used_35mm_rotarychaingun",
          "used_katana",
          "used_35mm_cannon",
          "used_reaver_weapons",
          "used_lightning_weapons",
          "used_med_app",
          "used_20mm_cannon",
          "visited_monolith_forseral",
          "used_105mm_cannon",
          "used_15mm_chaingun",
          "used_rotarychaingun",
          "visited_deconstruction_terminal",
          "used_skyguard_weapons",
          "visited_generator",
          "used_trek",
          "used_vanguard_weapons",
          "visited_ancient_air_vehicle_terminal",
          "visited_ancient_equipment_terminal",
          "visited_order_terminal",
          "visited_ground_vehicle_terminal",
          "used_vulture_bombardier",
          "used_vulture_nose_cannon",
          "used_vulture_tail_cannon",
          "used_wasp_weapon_system",
          "ugd05",
          "ugd04",
          "ugd03",
          "ugd02",
          "ugd01",
          "map99",
          "map98",
          "map97",
          "map15",
          "map14",
          "map12",
          "map04",
          "map05",
          "map03",
          "map01",
          "map06",
          "map02",
          "map09",
          "map07",
          "map10"
        ),
        List(),
        0,
        0,
        0,
        0,
        0,
        None,
        List(
          9, 16, 17, 69, 107, 108, 114, 115, 134, 171, 178, 196, 199, 222, 229, 283, 297, 347, 360, 391, 399, 421
        ),
        List(),
        false,
        None
      )
      val char: Option[Int] => DetailedCharacterData =
        (pad_length: Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)

      val inv: InventoryData = InventoryData(
        List(
          InternalSlot(
            730,
            PlanetSideGUID(3465),
            0,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(
                InternalSlot(
                  28,
                  PlanetSideGUID(3722),
                  0,
                  DetailedAmmoBoxData(
                    CommonFieldData(
                      PlanetSideEmpire.NEUTRAL,
                      false,
                      false,
                      true,
                      None,
                      false,
                      None,
                      None,
                      PlanetSideGUID(0)
                    ),
                    20
                  )
                )
              ),
              false
            )
          ),
          InternalSlot(
            845,
            PlanetSideGUID(4929),
            2,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(
                InternalSlot(
                  28,
                  PlanetSideGUID(4736),
                  0,
                  DetailedAmmoBoxData(
                    CommonFieldData(
                      PlanetSideEmpire.NEUTRAL,
                      false,
                      false,
                      true,
                      None,
                      false,
                      None,
                      None,
                      PlanetSideGUID(0)
                    ),
                    25
                  )
                )
              ),
              false
            )
          ),
          InternalSlot(
            175,
            PlanetSideGUID(3332),
            4,
            DetailedWeaponData(
              CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              0,
              List(
                InternalSlot(
                  540,
                  PlanetSideGUID(3778),
                  0,
                  DetailedAmmoBoxData(
                    CommonFieldData(
                      PlanetSideEmpire.NEUTRAL,
                      false,
                      false,
                      true,
                      None,
                      false,
                      None,
                      None,
                      PlanetSideGUID(0)
                    ),
                    1
                  )
                )
              ),
              false
            )
          ),
          InternalSlot(
            456,
            PlanetSideGUID(5302),
            5,
            DetailedLockerContainerData(
              CommonFieldData(
                PlanetSideEmpire.NEUTRAL,
                false,
                false,
                false,
                None,
                false,
                None,
                None,
                PlanetSideGUID(0)
              ),
              Some(
                InventoryData(
                  List(
                    InternalSlot(
                      714,
                      PlanetSideGUID(2628),
                      0,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(5819),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(2433),
                      9,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(3627),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(3916),
                      18,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(3069),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      324,
                      PlanetSideGUID(5514),
                      29,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            540,
                            PlanetSideGUID(4940),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              1
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(2669),
                      90,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(2277),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(5365),
                      99,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(5604),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(5884),
                      108,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(5765),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(5137),
                      180,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(3016),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(4475),
                      189,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(4237),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(3841),
                      198,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(5485),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(4075),
                      270,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(4451),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      462,
                      PlanetSideGUID(4620),
                      279,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            463,
                            PlanetSideGUID(2357),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              150
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(3175),
                      288,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(5363),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(5391),
                      369,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(2801),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(4384),
                      378,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(3584),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              16
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      577,
                      PlanetSideGUID(2294),
                      459,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            111,
                            PlanetSideGUID(5454),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              78
                            )
                          )
                        ),
                        false
                      )
                    ),
                    InternalSlot(
                      714,
                      PlanetSideGUID(5111),
                      465,
                      DetailedWeaponData(
                        CommonFieldData(
                          PlanetSideEmpire.NEUTRAL,
                          false,
                          false,
                          false,
                          None,
                          false,
                          None,
                          None,
                          PlanetSideGUID(0)
                        ),
                        0,
                        List(
                          InternalSlot(
                            755,
                            PlanetSideGUID(5068),
                            0,
                            DetailedAmmoBoxData(
                              CommonFieldData(
                                PlanetSideEmpire.NEUTRAL,
                                false,
                                false,
                                false,
                                None,
                                false,
                                None,
                                None,
                                PlanetSideGUID(0)
                              ),
                              15
                            )
                          )
                        ),
                        false
                      )
                    )
                  )
                )
              )
            )
          ),
          InternalSlot(
            28,
            PlanetSideGUID(4386),
            6,
            DetailedAmmoBoxData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              50
            )
          ),
          InternalSlot(
            28,
            PlanetSideGUID(3548),
            9,
            DetailedAmmoBoxData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              50
            )
          ),
          InternalSlot(
            28,
            PlanetSideGUID(4103),
            12,
            DetailedAmmoBoxData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              50
            )
          ),
          InternalSlot(
            28,
            PlanetSideGUID(5179),
            33,
            DetailedAmmoBoxData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              50
            )
          ),
          InternalSlot(
            29,
            PlanetSideGUID(3733),
            36,
            DetailedAmmoBoxData(
              CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
              50
            )
          ),
          InternalSlot(
            728,
            PlanetSideGUID(4731),
            39,
            DetailedREKData(
              CommonFieldData(
                PlanetSideEmpire.TR,
                false,
                false,
                true,
                None,
                false,
                Some(false),
                None,
                PlanetSideGUID(0)
              ),
              16
            )
          )
        )
      )
      val obj = DetailedPlayerData.apply(pos, app, char, inv, DrawnSlot.None)

      val msg      = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(3390), obj)
      val pkt      = PacketCoding.encodePacket(msg).require.toByteVector
      val pkt_bitv = pkt.toBitVector
      val ori_bitv = string_xrider912.toBitVector
      pkt_bitv.take(140) mustEqual ori_bitv.take(140) //skip 1; this is the highest bit of PlacementData::Orientation::z
      pkt_bitv.drop(141) mustEqual ori_bitv.drop(141)
      //TODO work on DetailedCharacterData to make this pass as a single stream
    }
  }
}
