mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-04-28 07:45:28 +00:00
Lump of Coal (#982)
* preliminary elements needed to battle frame robotics; mostly from previous branch * introduction of FrameVehicleStateMessage and anticipated event system paths for BFR's; spawning amenities for BFR's are parsed and built from the zonemap files, but their coordinates are currently incorrect, and the resulting entity will not function atm * bfr's spawn correctly; default arm weapons will spawn correctly; bfr rearm terminal added but arm swap not working correctly; bfr shields charge if not full; proper separation of vehicle spawn pad types * arm weapon swapping in bfr's; swapped weapons switch, contextually, to either *_left or to *_right depending on the mounting; partial support for entities that do not have an OCDM packet form * crouching improves shield regeneration * some projectiles damage the bfr regardless of its shield * delay the final vehicle explosion; start of vehicle subsystems * handling for bfr shield ui updates; more of vehicle subsystems; corrections to TradeMessage packet; clarifications for FrameVehicleStateMessage package; report on flight status of bfr's * control agency support for vehicle subsystems for arm weapon fire control * vehicle capacitor, for what it's worth; shield and capacitor are influenced by recharge freeze and drain * initial packet and tests for AvatarAwardMessage; update the fields of FreindsResponse, DetailedCharacterData, and LoadoutType for FavoritesMessage; corrections to intiailization packets in SessionActor; players start as imprinted by default * support for GOAM and GAM integration into vehicle control agencies using a basic actor superclass; addition of vehicle subsystems; modifications to bfr control agency to allow for weapon handiness and subsystem control; fixed Fit mapping for vehicle override; made mountable seat transcoders independent * delayed explosions to accompany the delayed death for the bfr; bfr terminal window closes on successful purchase * the bfr armor siphon works * clarification for bfr inventory item manipulation; corrections to length of bfr transcoder for flight variants; everything else in in support of the various arm weapons that can be assigned to the bfr, including damage proxy support for causing/interacting with/cleaning up after radiation cloud projectiles * fixed the apc emp burst; fixed bfr arm weapon manipulation for activated subsystem; armor and ntu siphon support * battleframe loadouts available upon vehicle spawn (vs and tr only) * adb values for siphons; subsystem update message; some repairs * cargo vehicles are subject to radiation damage; damage for battleframes are different depending on shield evasion status; battleframe loadout deleting supported; bfr kill box; automatically wire bfr sheds, includeing the ones in sanctuary * proper bfr spawn angles; bfr vehicle timers; projectiles are no longer radiation clouds by default; better remote projectile cleanup; resolving incorrect weapon arm enabled states for bfrs * added tests for FrameVehicleState and GenericObjectActionAtPosition; pass around maximum sector for zone interactions * changed the triggers for the stamina regeneration timer * potential fix for issue related to finding arm weapon mounts * modifications to how vehicle subsystems are automated; jammer field updates; support and passing around custom block map ranges; does include activated dev tests for battleframe PAM, which will need to be stripped out later * commit while working on subsystems mk2 * subsystems fail when jammed; an unoccupied bfr does not have shields active; pulling a bfr of one variant should block the other variant too * fix distance check with radiation clouds; blocked bfr weaponry from anywhere but bfr arm mounts and cursor; ammunition depletion of aphelion laser; bfr shields deactivates when unoccupied * significant modifications to vehicle subsystem operations; disambiguation of weapon subsystems; debuffs to charge rate and use rate for the capacitor and shield of bfr; test for ComponentDamageMessage; somewhat proper jammering operations for bfr
This commit is contained in:
parent
46763b7877
commit
6ae0b44848
140 changed files with 10426 additions and 2462 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
|
||||
class Vector3Test extends Specification {
|
||||
val vec = Vector3(1.3f, -2.6f, 3.9f)
|
||||
|
|
@ -321,4 +321,20 @@ class Vector3Test extends Specification {
|
|||
Vector3.relativeUp(Vector3(270, 90, 0)) mustEqual Vector3(1,0,0) //east
|
||||
}
|
||||
}
|
||||
|
||||
"Angular" should {
|
||||
"convert from clockwise to counterclockwise" in {
|
||||
Angular.flipClockwise(angle = -45f) mustEqual 135f
|
||||
Angular.flipClockwise(angle = 0f) mustEqual 90f
|
||||
Angular.flipClockwise(angle = 45f) mustEqual 45f
|
||||
Angular.flipClockwise(angle = 90f) mustEqual 0f
|
||||
Angular.flipClockwise(angle = 135f) mustEqual 315f
|
||||
Angular.flipClockwise(angle = 180f) mustEqual 270f
|
||||
Angular.flipClockwise(angle = 225f) mustEqual 225f
|
||||
Angular.flipClockwise(angle = 270f) mustEqual 180f
|
||||
Angular.flipClockwise(angle = 315f) mustEqual 135f
|
||||
Angular.flipClockwise(angle = 360f) mustEqual 90f
|
||||
Angular.flipClockwise(angle = 405f) mustEqual 45f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
67
src/test/scala/game/AvatarAwardMessageTest.scala
Normal file
67
src/test/scala/game/AvatarAwardMessageTest.scala
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package game
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import scodec.bits._
|
||||
|
||||
class AvatarAwardMessageTest extends Specification {
|
||||
val string0 = hex"cf 15010000014000003d0040000000"
|
||||
val string1 = hex"cf 2a010000c717b12a0000"
|
||||
val string2 = hex"cf a6010000e9058cab0080"
|
||||
|
||||
"decode (0)" in {
|
||||
PacketCoding.decodePacket(string0).require match {
|
||||
case AvatarAwardMessage(unk1, unk2, unk3) =>
|
||||
unk1 mustEqual 277
|
||||
unk2 mustEqual AwardOptionZero(5, 500)
|
||||
unk3 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (1)" in {
|
||||
PacketCoding.decodePacket(string1).require match {
|
||||
case AvatarAwardMessage(unk1, unk2, unk3) =>
|
||||
unk1 mustEqual 298
|
||||
unk2 mustEqual AwardOptionTwo(2831441436L)
|
||||
unk3 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (2)" in {
|
||||
PacketCoding.decodePacket(string2).require match {
|
||||
case AvatarAwardMessage(unk1, unk2, unk3) =>
|
||||
unk1 mustEqual 422
|
||||
unk2 mustEqual AwardOptionTwo(2888963748L)
|
||||
unk3 mustEqual 2
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
val msg = AvatarAwardMessage(277, AwardOptionZero(5, 500), 0)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string0
|
||||
}
|
||||
|
||||
"encode (1)" in {
|
||||
val msg = AvatarAwardMessage(298, AwardOptionTwo(2831441436L), 0)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string1
|
||||
}
|
||||
|
||||
"encode (2)" in {
|
||||
val msg = AvatarAwardMessage(422, AwardOptionTwo(2888963748L), 2)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string2
|
||||
}
|
||||
}
|
||||
68
src/test/scala/game/ComponentDamageMessageTest.scala
Normal file
68
src/test/scala/game/ComponentDamageMessageTest.scala
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package game
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideGUID, SubsystemComponent}
|
||||
import scodec.bits._
|
||||
|
||||
class ComponentDamageMessageTest extends Specification {
|
||||
val string_on = hex"d3 8f01 1a000000820000000000202040"
|
||||
val string_off = hex"d3 8f01 1a00000000"
|
||||
|
||||
"decode (on)" in {
|
||||
PacketCoding.decodePacket(string_on).require match {
|
||||
case ComponentDamageMessage(guid, code, data) =>
|
||||
guid mustEqual PlanetSideGUID(399)
|
||||
code mustEqual SubsystemComponent.WeaponSystemsCOFRecovery
|
||||
data match {
|
||||
case Some(ComponentDamageField(u2, u3, u4)) =>
|
||||
u2 mustEqual 4
|
||||
u3 mustEqual 1077936128
|
||||
u4 mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (off)" in {
|
||||
PacketCoding.decodePacket(string_off).require match {
|
||||
case ComponentDamageMessage(guid, code, data) =>
|
||||
guid mustEqual PlanetSideGUID(399)
|
||||
code mustEqual SubsystemComponent.WeaponSystemsCOFRecovery
|
||||
data.isEmpty mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (on)" in {
|
||||
val msg = ComponentDamageMessage(
|
||||
PlanetSideGUID(399),
|
||||
SubsystemComponent.WeaponSystemsCOFRecovery,
|
||||
Some(ComponentDamageField(4, 1077936128, unk = true))
|
||||
)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_on
|
||||
}
|
||||
|
||||
"encode (off; 1)" in {
|
||||
val msg = ComponentDamageMessage(PlanetSideGUID(399), SubsystemComponent.WeaponSystemsCOFRecovery, None)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_off
|
||||
}
|
||||
|
||||
"encode (off; 2)" in {
|
||||
val msg = ComponentDamageMessage(PlanetSideGUID(399), SubsystemComponent.WeaponSystemsCOFRecovery)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_off
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ class FavoritesMessageTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (for infantry)" in {
|
||||
val msg = FavoritesMessage(LoadoutType.Infantry, PlanetSideGUID(3760), 0, "Agile (basic)", 1)
|
||||
val msg = FavoritesMessage.Infantry(PlanetSideGUID(3760), line = 0, label = "Agile (basic)", armor = 1)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual stringInfantry
|
||||
|
|
@ -46,7 +46,7 @@ class FavoritesMessageTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (for vehicles)" in {
|
||||
val msg = FavoritesMessage(LoadoutType.Vehicle, PlanetSideGUID(4210), 0, "Skyguard")
|
||||
val msg = FavoritesMessage.Vehicle(PlanetSideGUID(4210), line = 0, label = "Skyguard")
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual stringVehicles
|
||||
|
|
|
|||
57
src/test/scala/game/FrameVehicleStateMessageTest.scala
Normal file
57
src/test/scala/game/FrameVehicleStateMessageTest.scala
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package game
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
import scodec.bits._
|
||||
|
||||
class FrameVehicleStateMessageTest extends Specification {
|
||||
val string = hex"1c b101 087778ad7e62609ddf771beee0647fc6001a0000000000000000"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.decodePacket(string).require match {
|
||||
case FrameVehicleStateMessage(guid, unk1, pos, ang, vel, unk2, unk3, unk4, crouched, airborne, ascending, ftime, u9, uA) =>
|
||||
guid mustEqual PlanetSideGUID(433)
|
||||
unk1 mustEqual 0
|
||||
pos mustEqual Vector3(6518.5234f, 1918.6719f, 16.296875f)
|
||||
ang mustEqual Vector3(353.67188f, 6.328125f, 130.42969f)
|
||||
vel.contains(Vector3(21.0375f, -17.55f, 27.1125f)) mustEqual true
|
||||
unk2 mustEqual false
|
||||
unk3 mustEqual 0
|
||||
unk4 mustEqual 0
|
||||
crouched mustEqual false
|
||||
airborne mustEqual false
|
||||
ascending mustEqual true
|
||||
ftime mustEqual 10
|
||||
u9 mustEqual 0
|
||||
uA mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = FrameVehicleStateMessage(
|
||||
PlanetSideGUID(433),
|
||||
0,
|
||||
Vector3(6518.5234f, 1918.6719f, 16.296875f),
|
||||
Vector3(353.67188f, 6.328125f, 130.42969f),
|
||||
Some(Vector3(21.0375f, -17.55f, 27.1125f)),
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
10,
|
||||
0,
|
||||
0
|
||||
)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package game
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
import scodec.bits._
|
||||
|
||||
class GenericObjectActionAtPositionMessageTest extends Specification {
|
||||
val string = hex"d4 d504 09 00060 00110 000e" //faked
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.decodePacket(string).require match {
|
||||
case GenericObjectActionAtPositionMessage(object_guid, action, pos) =>
|
||||
object_guid mustEqual PlanetSideGUID(1237)
|
||||
action mustEqual 9
|
||||
pos mustEqual Vector3(12f, 34f, 56f)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = GenericObjectActionAtPositionMessage(PlanetSideGUID(1237), 9, Vector3(12f, 34f, 56f))
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package game.objectcreate
|
||||
|
||||
import net.psforever.packet.PacketCoding
|
||||
import net.psforever.packet.game.ObjectCreateMessage
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import org.specs2.mutable._
|
||||
import scodec.bits._
|
||||
|
||||
class RadiationCloudDataTest extends Specification {
|
||||
val string = hex"17 a5000000 e6a5905 35e6e 52141 bf02 00 00 00 2400000"
|
||||
|
||||
"CaptureFlagData" in {
|
||||
"decode" in {
|
||||
PacketCoding.decodePacket(string).require match {
|
||||
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
||||
len mustEqual 165
|
||||
cls mustEqual ObjectClass.radiator_cloud
|
||||
guid mustEqual PlanetSideGUID(1369)
|
||||
parent.isDefined mustEqual false
|
||||
data match {
|
||||
case RadiationCloudData(pos, faction) =>
|
||||
pos.coord mustEqual Vector3(7628.414f, 552.6406f, 10.984375f)
|
||||
pos.orient mustEqual Vector3.z(value = 90)
|
||||
pos.vel.isEmpty mustEqual true
|
||||
faction mustEqual PlanetSideEmpire.VS
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val obj = RadiationCloudData(PlacementData(7628.414f, 552.6406f, 10.984375f, 0f, 0f, 90f), PlanetSideEmpire.VS)
|
||||
val msg = ObjectCreateMessage(ObjectClass.radiator_cloud, PlanetSideGUID(1369), obj)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
pkt mustEqual string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
|
||||
b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
|
||||
b.unkA mustEqual Nil
|
||||
b.unkB mustEqual Nil
|
||||
b.unkC mustEqual false
|
||||
|
|
@ -348,7 +348,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
|
||||
b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
|
||||
b.unkA mustEqual Nil
|
||||
b.unkB mustEqual Nil
|
||||
b.unkC mustEqual false
|
||||
|
|
@ -575,7 +575,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
|
||||
b.imprinting.contains(ImprintingProgress(0, 0)) mustEqual true
|
||||
b.unkA mustEqual Nil
|
||||
b.unkB mustEqual Nil
|
||||
b.unkC mustEqual false
|
||||
|
|
@ -1073,7 +1073,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.isEmpty mustEqual true
|
||||
b.imprinting.isEmpty mustEqual true
|
||||
b.unkA mustEqual Nil
|
||||
b.unkB mustEqual Nil
|
||||
b.unkC mustEqual false
|
||||
|
|
@ -1294,7 +1294,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.isEmpty mustEqual true
|
||||
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,
|
||||
|
|
@ -1432,7 +1432,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
b.unk6 mustEqual 0L
|
||||
b.unk7 mustEqual 0L
|
||||
b.unk8 mustEqual 0L
|
||||
b.unk9.isEmpty mustEqual true
|
||||
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
|
||||
|
|
@ -1614,7 +1614,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
0L,
|
||||
0L,
|
||||
0L,
|
||||
Some(DCDExtra2(0, 0)),
|
||||
Some(ImprintingProgress(0, 0)),
|
||||
Nil,
|
||||
Nil,
|
||||
false,
|
||||
|
|
@ -1796,7 +1796,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
0L,
|
||||
0L,
|
||||
0L,
|
||||
Some(DCDExtra2(0, 0)),
|
||||
Some(ImprintingProgress(0, 0)),
|
||||
Nil,
|
||||
Nil,
|
||||
false,
|
||||
|
|
@ -2022,7 +2022,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
0L,
|
||||
0L,
|
||||
0L,
|
||||
Some(DCDExtra2(0, 0)),
|
||||
Some(ImprintingProgress(0, 0)),
|
||||
Nil,
|
||||
Nil,
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,350 @@
|
|||
// 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, 2)(false))
|
||||
)
|
||||
)
|
||||
),
|
||||
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, 2)(false))
|
||||
)
|
||||
)
|
||||
),
|
||||
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, 2)(false))
|
||||
)
|
||||
)
|
||||
)
|
||||
)))
|
||||
)
|
||||
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, 2)(false))
|
||||
)
|
||||
)
|
||||
),
|
||||
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, 2)(false))
|
||||
)
|
||||
)
|
||||
)
|
||||
)))
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.aphelion_flight, PlanetSideGUID(393), obj)
|
||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_aphelion_flight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,12 +253,12 @@ class MountedVehiclesTest extends Specification {
|
|||
)
|
||||
)
|
||||
)
|
||||
val player = VehicleData.PlayerData(
|
||||
val player = MountableInventory.PlayerData(
|
||||
app,
|
||||
char,
|
||||
inv,
|
||||
DrawnSlot.None,
|
||||
VehicleData.InitialStreamLengthToSeatEntries(true, VehicleFormat.Variant)
|
||||
MountableInventory.InitialStreamLengthToSeatEntries(true, VehicleFormat.Variant)
|
||||
)
|
||||
val obj = VehicleData(
|
||||
PlacementData(
|
||||
|
|
|
|||
|
|
@ -874,7 +874,7 @@ class ConverterTest extends Specification {
|
|||
val fury_def = VehicleDefinition(ObjectClass.fury)
|
||||
fury_def.Seats += 0 -> new SeatDefinition()
|
||||
fury_def.Seats(0).bailable = true
|
||||
fury_def.controlledWeapons += 0 -> 1
|
||||
fury_def.controlledWeapons(0, 1)
|
||||
fury_def.MountPoints += 0 -> MountInfo(0)
|
||||
fury_def.MountPoints += 2 -> MountInfo(0)
|
||||
fury_def.Weapons += 1 -> fury_weapon_systema_def
|
||||
|
|
@ -889,8 +889,8 @@ class ConverterTest extends Specification {
|
|||
fury.Faction = PlanetSideEmpire.VS
|
||||
fury.Position = Vector3(3674.8438f, 2732f, 91.15625f)
|
||||
fury.Orientation = Vector3(0.0f, 0.0f, 90.0f)
|
||||
fury.WeaponControlledFromSeat(0).get.GUID = PlanetSideGUID(400)
|
||||
fury.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box = hellfire_ammo_box
|
||||
fury.WeaponControlledFromSeat(0).head.GUID = PlanetSideGUID(400)
|
||||
fury.WeaponControlledFromSeat(0).head.asInstanceOf[Tool].AmmoSlots.head.Box = hellfire_ammo_box
|
||||
|
||||
fury.Definition.Packet.ConstructorData(fury).isSuccess mustEqual true
|
||||
ok //TODO write more of this test
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class DamageCalculationsTests extends Specification {
|
|||
}
|
||||
|
||||
"extract damage against battleframe robotics" in {
|
||||
AgainstBFR(proj_prof) == proj_prof.Damage4 mustEqual true
|
||||
AgainstBfr(proj_prof) == proj_prof.Damage4 mustEqual true
|
||||
}
|
||||
|
||||
"no degrade damage modifier" in {
|
||||
|
|
|
|||
|
|
@ -1437,9 +1437,9 @@ class DamageableVehicleJammeringMountedTest extends FreedContextActorTest {
|
|||
|
||||
"handle jammering with mounted vehicles" in {
|
||||
assert(lodestar.Health == lodestar.Definition.DefaultHealth)
|
||||
assert(!lodestar.Jammered)
|
||||
assert(!lodestar.Jammed)
|
||||
assert(atv.Health == atv.Definition.DefaultHealth)
|
||||
assert(!atv.Jammered)
|
||||
assert(!atv.Jammed)
|
||||
|
||||
lodestar.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg12 = vehicleProbe.receiveOne(500 milliseconds)
|
||||
|
|
@ -1684,11 +1684,11 @@ class DamageableVehicleDestroyMountedTest extends FreedContextActorTest {
|
|||
lodestar.Health = lodestar.Definition.DamageDestroysAt + 1 //initial state manip
|
||||
atv.Shields = 1 //initial state manip
|
||||
assert(lodestar.Health > lodestar.Definition.DamageDestroysAt)
|
||||
assert(!lodestar.Jammered)
|
||||
assert(!lodestar.Jammed)
|
||||
assert(!lodestar.Destroyed)
|
||||
assert(atv.Health == atv.Definition.DefaultHealth)
|
||||
assert(atv.Shields == 1)
|
||||
assert(!atv.Jammered)
|
||||
assert(!atv.Jammed)
|
||||
assert(!atv.Destroyed)
|
||||
|
||||
lodestar.Actor ! Vitality.Damage(applyDamageToA)
|
||||
|
|
|
|||
|
|
@ -861,7 +861,6 @@ object GeneratorTest {
|
|||
Repairable = true
|
||||
RepairDistance = 13.5f
|
||||
RepairIfDestroyed = true
|
||||
explodes = true
|
||||
innateDamage = new DamageWithPosition {
|
||||
DamageRadius = 14
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class VehicleTest extends Specification {
|
|||
fury_vehicle.Weapons.get(1).isDefined mustEqual true
|
||||
fury_vehicle.Weapons(1).Equipment.isDefined mustEqual true
|
||||
fury_vehicle.Weapons(1).Equipment.get.Definition mustEqual GlobalDefinitions.fury.Weapons(1)
|
||||
fury_vehicle.WeaponControlledFromSeat(0) mustEqual fury_vehicle.Weapons(1).Equipment
|
||||
fury_vehicle.WeaponControlledFromSeat(0) contains fury_vehicle.Weapons(1).Equipment.get mustEqual true
|
||||
fury_vehicle.Trunk.Width mustEqual 11
|
||||
fury_vehicle.Trunk.Height mustEqual 11
|
||||
fury_vehicle.Trunk.Offset mustEqual 30
|
||||
|
|
@ -248,7 +248,7 @@ class VehicleTest extends Specification {
|
|||
chaingun_p.isDefined mustEqual true
|
||||
|
||||
harasser_vehicle.WeaponControlledFromSeat(0).isEmpty mustEqual true
|
||||
harasser_vehicle.WeaponControlledFromSeat(1) mustEqual chaingun_p
|
||||
harasser_vehicle.WeaponControlledFromSeat(1).contains(chaingun_p.get) mustEqual true
|
||||
}
|
||||
|
||||
"can filter utilities with indices that are natural numbers" in {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ class GUIDTaskRegisterVehicleTest extends ActorTest {
|
|||
"RegisterVehicle" in {
|
||||
val (_, uns, probe) = GUIDTaskTest.CommonTestSetup
|
||||
val obj = Vehicle(GlobalDefinitions.fury)
|
||||
val obj_wep = obj.WeaponControlledFromSeat(0).get
|
||||
val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box =
|
||||
val obj_wep = obj.WeaponControlledFromSeat(0).head
|
||||
val obj_wep_ammo = (obj_wep.asInstanceOf[Tool].AmmoSlots.head.Box =
|
||||
AmmoBox(GlobalDefinitions.hellfire_ammo)).get
|
||||
obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo)
|
||||
val obj_trunk_ammo = obj.Trunk.Items(0).obj
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ class GUIDTaskUnregisterVehicleTest extends ActorTest {
|
|||
"RegisterVehicle" in {
|
||||
val (guid, uns, probe) = GUIDTaskTest.CommonTestSetup
|
||||
val obj = Vehicle(GlobalDefinitions.fury)
|
||||
val obj_wep = obj.WeaponControlledFromSeat(0).get
|
||||
val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box =
|
||||
val obj_wep = obj.WeaponControlledFromSeat(0).head
|
||||
val obj_wep_ammo = (obj_wep.asInstanceOf[Tool].AmmoSlots.head.Box =
|
||||
AmmoBox(GlobalDefinitions.hellfire_ammo)).get
|
||||
obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo)
|
||||
val obj_trunk_ammo = obj.Trunk.Items(0).obj
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue