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:
Fate-JH 2022-01-27 09:57:51 -05:00 committed by GitHub
parent 46763b7877
commit 6ae0b44848
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
140 changed files with 10426 additions and 2462 deletions

View file

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

View 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
}
}

View 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
}
}

View file

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

View 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
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -861,7 +861,6 @@ object GeneratorTest {
Repairable = true
RepairDistance = 13.5f
RepairIfDestroyed = true
explodes = true
innateDamage = new DamageWithPosition {
DamageRadius = 14
}

View file

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

View file

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

View file

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