mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
* fixed about half of the unworking tests, and commented out one * stubborn tests that pass on their own but don't tend to pass in clusters; also, a certain test that terminates an actor when a mostly unrelated entity has its propertries changed from default, just weird * reviewing logic and operations pairs to ensure that functionality should have been retained from parent structure; moving handling case from individual player modes to session actor, which makes it much closer to the pattern * while it's still a dice roll, all tests currently implemented are capable of passing * deployable vehicles should properly deploy again now that they don't have to fight with themselves for the ability to deploy * boomers are no longer owned if the trigger is dropped (how long has this been not working?) * redid DamageFeedbackMessage packet because I thought I could use it for something; didn't use it for anything; boomers are no longer responsive to explosive sympathy * redid combat engineering explosive logic * redid (cleaned-up) implant logic * implant initialization timers now saved to the database; uninitialized implants will appear as uninitialized when the character loads; passive initialized implants will always start as activate * renaming methods; progress bar calculations change * accounting for implants that are in the act of being initialized
350 lines
15 KiB
Scala
350 lines
15 KiB
Scala
// Copyright (c) 2021 PSForever
|
|
package game.objectcreatevehicle
|
|
|
|
import net.psforever.packet._
|
|
import net.psforever.packet.game.objectcreate._
|
|
import net.psforever.packet.game.ObjectCreateMessage
|
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
|
import org.specs2.mutable._
|
|
import scodec.bits._
|
|
|
|
class BattleframeRoboticsTest extends Specification {
|
|
val string_aphelion_gunner = hex"17 80 02 00 00 AA 0B F0 15 EB 1C FE C3 30 90 40 00 00 E4 40 00 0F FF F0 00 00 F2 08 18 CC 13 C0 60 B2 00 00 00 10 11 94 2A 00 C0 64 00 00 1A 04 D8 0C 1E 40 00 00 02 02 32 85 60 18 0C 80 00 03 10 99 01 84 C8 00 00 00 40 46 10 CE 03 01 90 00 00"
|
|
val string_aphelion_flight = hex"17 f6010000 a98 8901 5eb1c fec33 0904 00 00 0e4 40000ffff0000002040866102030390000000808ca1cc0603200000d0140060b20000001011943c00c06400000"
|
|
|
|
"Battle Frame Robotics" should {
|
|
"decode (aphelion)" in {
|
|
PacketCoding.decodePacket(string_aphelion_gunner).require match {
|
|
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
|
len mustEqual 640L
|
|
cls mustEqual ObjectClass.aphelion_gunner
|
|
guid mustEqual PlanetSideGUID(447)
|
|
parent.isDefined mustEqual false
|
|
data match {
|
|
case BattleFrameRoboticsData(pos, vdata, health, shields, unk1, unk2, no_mount_points, drive_state, proper_anim, unk3, show_shield, unk4, Some(inv)) =>
|
|
pos.coord mustEqual Vector3(6498.7344f, 1927.9844f, 16.140625f)
|
|
pos.orient mustEqual Vector3.z(50.625f)
|
|
pos.vel.isEmpty mustEqual true
|
|
|
|
vdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, vguid) =>
|
|
faction mustEqual PlanetSideEmpire.VS
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.isEmpty mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
vguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
health mustEqual 255
|
|
shields mustEqual 255
|
|
unk1 mustEqual 0
|
|
unk2 mustEqual false
|
|
no_mount_points mustEqual false
|
|
drive_state mustEqual 60
|
|
proper_anim mustEqual true
|
|
unk3 mustEqual 0
|
|
show_shield mustEqual false
|
|
unk4.isEmpty mustEqual true
|
|
|
|
inv match {
|
|
case InventoryData(list) =>
|
|
list.head.objectClass mustEqual ObjectClass.aphelion_ppa_left
|
|
list.head.guid mustEqual PlanetSideGUID(335)
|
|
list.head.parentSlot mustEqual 2
|
|
list.head.obj match {
|
|
case WeaponData(wdata, fire_mode, ammo, unk) =>
|
|
wdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, wguid) =>
|
|
faction mustEqual PlanetSideEmpire.NEUTRAL
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.contains(false) mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
wguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
fire_mode mustEqual 0
|
|
ammo.head.objectClass mustEqual ObjectClass.aphelion_ppa_ammo
|
|
ammo.head.guid mustEqual PlanetSideGUID(340)
|
|
ammo.head.parentSlot mustEqual 0
|
|
unk mustEqual false
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
list(1).objectClass mustEqual ObjectClass.aphelion_ppa_right
|
|
list(1).guid mustEqual PlanetSideGUID(411)
|
|
list(1).parentSlot mustEqual 3
|
|
list(1).obj match {
|
|
case WeaponData(wdata, fire_mode, ammo, unk) =>
|
|
wdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, wguid) =>
|
|
faction mustEqual PlanetSideEmpire.NEUTRAL
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.contains(false) mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
wguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
fire_mode mustEqual 0
|
|
ammo.head.objectClass mustEqual ObjectClass.aphelion_ppa_ammo
|
|
ammo.head.guid mustEqual PlanetSideGUID(342)
|
|
ammo.head.parentSlot mustEqual 0
|
|
unk mustEqual false
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
list(2).objectClass mustEqual ObjectClass.aphelion_plasma_rocket_pod
|
|
list(2).guid mustEqual PlanetSideGUID(409)
|
|
list(2).parentSlot mustEqual 4
|
|
list(2).obj match {
|
|
case WeaponData(wdata, fire_mode, ammo, unk) =>
|
|
wdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, wguid) =>
|
|
faction mustEqual PlanetSideEmpire.NEUTRAL
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.contains(false) mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
wguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
fire_mode mustEqual 0
|
|
ammo.head.objectClass mustEqual ObjectClass.aphelion_plasma_rocket_ammo
|
|
ammo.head.guid mustEqual PlanetSideGUID(359)
|
|
ammo.head.parentSlot mustEqual 0
|
|
unk mustEqual false
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
}
|
|
|
|
"decode (eclipse)" in {
|
|
PacketCoding.decodePacket(string_aphelion_flight).require match {
|
|
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
|
len mustEqual 502L
|
|
cls mustEqual ObjectClass.aphelion_flight
|
|
guid mustEqual PlanetSideGUID(393)
|
|
parent.isDefined mustEqual false
|
|
data match {
|
|
case BattleFrameRoboticsData(pos, vdata, health, shields, unk1, unk2, no_mount_points, drive_state, proper_anim, unk3, show_shield, unk4, Some(inv)) =>
|
|
pos.coord mustEqual Vector3(6498.7344f, 1927.9844f, 16.140625f)
|
|
pos.orient mustEqual Vector3.z(50.625f)
|
|
pos.vel.isEmpty mustEqual true
|
|
|
|
vdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, vguid) =>
|
|
faction mustEqual PlanetSideEmpire.VS
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.isEmpty mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
vguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
health mustEqual 255
|
|
shields mustEqual 255
|
|
unk1 mustEqual 0
|
|
unk2 mustEqual false
|
|
no_mount_points mustEqual false
|
|
drive_state mustEqual 0
|
|
proper_anim mustEqual true
|
|
unk3 mustEqual 0
|
|
show_shield mustEqual false
|
|
unk4.contains(false) mustEqual true
|
|
|
|
inv match {
|
|
case InventoryData(list) =>
|
|
list.head.objectClass mustEqual ObjectClass.aphelion_ppa_left
|
|
list.head.guid mustEqual PlanetSideGUID(385)
|
|
list.head.parentSlot mustEqual 1
|
|
list.head.obj match {
|
|
case WeaponData(wdata, fire_mode, ammo, unk) =>
|
|
wdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, wguid) =>
|
|
faction mustEqual PlanetSideEmpire.NEUTRAL
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.contains(false) mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
wguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
fire_mode mustEqual 0
|
|
ammo.head.objectClass mustEqual ObjectClass.aphelion_ppa_ammo
|
|
ammo.head.guid mustEqual PlanetSideGUID(371)
|
|
ammo.head.parentSlot mustEqual 0
|
|
unk mustEqual false
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
list(1).objectClass mustEqual ObjectClass.aphelion_ppa_right
|
|
list(1).guid mustEqual PlanetSideGUID(336)
|
|
list(1).parentSlot mustEqual 2
|
|
list(1).obj match {
|
|
case WeaponData(wdata, fire_mode, ammo, unk) =>
|
|
wdata match {
|
|
case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, wguid) =>
|
|
faction mustEqual PlanetSideEmpire.NEUTRAL
|
|
bops mustEqual false
|
|
alternate mustEqual false
|
|
v1 mustEqual true
|
|
v2.isEmpty mustEqual true
|
|
v3 mustEqual false
|
|
v4.contains(false) mustEqual true
|
|
v5.isEmpty mustEqual true
|
|
wguid mustEqual PlanetSideGUID(0)
|
|
case _ =>
|
|
ko
|
|
}
|
|
fire_mode mustEqual 0
|
|
ammo.head.objectClass mustEqual ObjectClass.aphelion_ppa_ammo
|
|
ammo.head.guid mustEqual PlanetSideGUID(376)
|
|
ammo.head.parentSlot mustEqual 0
|
|
unk mustEqual false
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
}
|
|
|
|
"encode (aphelion)" in {
|
|
val obj = BattleFrameRoboticsData(
|
|
PlacementData(6498.7344f, 1927.9844f, 16.140625f, 0, 0, 50.625f),
|
|
CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
|
|
255,
|
|
255,
|
|
0,
|
|
false,
|
|
false,
|
|
60,
|
|
true,
|
|
0,
|
|
false,
|
|
None,
|
|
Some(InventoryData(List(
|
|
InventoryItemData(ObjectClass.aphelion_ppa_left, PlanetSideGUID(335), 2,
|
|
WeaponData(
|
|
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
|
|
0,
|
|
List(
|
|
InternalSlot(ObjectClass.aphelion_ppa_ammo, PlanetSideGUID(340), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
|
|
)
|
|
)
|
|
),
|
|
InventoryItemData(ObjectClass.aphelion_ppa_right, PlanetSideGUID(411), 3,
|
|
WeaponData(
|
|
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
|
|
0,
|
|
List(
|
|
InternalSlot(ObjectClass.aphelion_ppa_ammo, PlanetSideGUID(342), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
|
|
)
|
|
)
|
|
),
|
|
InventoryItemData(ObjectClass.aphelion_plasma_rocket_pod, PlanetSideGUID(409), 4,
|
|
WeaponData(
|
|
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
|
|
0,
|
|
List(
|
|
InternalSlot(ObjectClass.aphelion_plasma_rocket_ammo, PlanetSideGUID(359), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
|
|
)
|
|
)
|
|
)
|
|
)))
|
|
)
|
|
val msg = ObjectCreateMessage(ObjectClass.aphelion_gunner, PlanetSideGUID(447), obj)
|
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
|
|
|
pkt mustEqual string_aphelion_gunner
|
|
}
|
|
|
|
"encode (eclipse)" in {
|
|
val obj = BattleFrameRoboticsData(
|
|
PlacementData(6498.7344f, 1927.9844f, 16.140625f, 0, 0, 50.625f),
|
|
CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
|
|
255,
|
|
255,
|
|
0,
|
|
false,
|
|
false,
|
|
0,
|
|
true,
|
|
0,
|
|
false,
|
|
Some(false),
|
|
Some(InventoryData(List(
|
|
InventoryItemData(ObjectClass.aphelion_ppa_left, PlanetSideGUID(385), 1,
|
|
WeaponData(
|
|
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
|
|
0,
|
|
List(
|
|
InternalSlot(ObjectClass.aphelion_ppa_ammo, PlanetSideGUID(371), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
|
|
)
|
|
)
|
|
),
|
|
InventoryItemData(ObjectClass.aphelion_ppa_right, PlanetSideGUID(336), 2,
|
|
WeaponData(
|
|
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
|
|
0,
|
|
List(
|
|
InternalSlot(ObjectClass.aphelion_ppa_ammo, PlanetSideGUID(376), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
|
|
)
|
|
)
|
|
)
|
|
)))
|
|
)
|
|
val msg = ObjectCreateMessage(ObjectClass.aphelion_flight, PlanetSideGUID(393), obj)
|
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
|
|
|
pkt mustEqual string_aphelion_flight
|
|
}
|
|
}
|
|
}
|