Merge pull request #1335 from psforever/empire_benefits_message_packet
Some checks failed
Publish Docs / docs (push) Has been cancelled
Publish Docker Image / docker (push) Has been cancelled
Test / test (push) Has been cancelled

EmpireBenefitsMessage packet
This commit is contained in:
Resaec 2025-12-18 13:27:44 +01:00 committed by GitHub
commit b8ea569b1c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 388 additions and 20 deletions

View file

@ -2924,9 +2924,11 @@ class ZoningOperations(
0 seconds
} else {
//for other zones ...
//Searhus lock benefit also gives biolab faster respawn
val searhusBenefit = Zones.zones.find(_.Number == 9).exists(_.benefitRecipient == player.Faction)
//biolabs have/grant benefits
val cryoBenefit: Float = toSpawnPoint.Owner match {
case b: Building if b.hasLatticeBenefit(LatticeBenefit.BioLaboratory) => 0.5f
case b: Building if b.hasLatticeBenefit(LatticeBenefit.BioLaboratory) || (b.BuildingType == StructureType.Facility && !b.CaptureTerminalIsHacked && searhusBenefit) => 0.5f
case _ => 1f
}
//TODO cumulative death penalty

View file

@ -5,6 +5,7 @@ import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.objects.{PlanetSideGameObject, Vehicle}
import net.psforever.packet.game.objectcreate._
import net.psforever.types.{DriveState, PlanetSideGUID, VehicleFormat}
import net.psforever.zones.Zones
import scala.util.{Failure, Success, Try}
@ -14,6 +15,8 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
override def ConstructorData(obj: Vehicle): Try[VehicleData] = {
val health = StatConverter.Health(obj.Health, obj.MaxHealth)
val boosted = if (Zones.zones.find(_.Number == 3).exists(_.benefitRecipient == obj.Faction)) true
else false
if (health > 0) { //active
Success(
VehicleData(
@ -32,7 +35,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
case None => PlanetSideGUID(0)
}
),
unk3 = false,
boostMaxHealth = boosted,
health,
unk4 = false,
no_mount_points = false,
@ -59,7 +62,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
v5 = None,
guid = PlanetSideGUID(0)
),
unk3 = false,
boostMaxHealth = boosted,
health = 0,
unk4 = false,
no_mount_points = true,

View file

@ -10,6 +10,7 @@ import net.psforever.objects.zones.Zone
import net.psforever.services.Service
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.types.Vector3
import net.psforever.zones.Zones
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
@ -44,6 +45,12 @@ class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnC
) //appear below the trench and doors
vehicle.WhichSide = pad.WhichSide
vehicle.Cloaked = vehicle.Definition.CanCloak && driver.Cloaked
// increase MaxHealth by 10% if driver has Cyssor empire armor benefit
if (Zones.zones.find(_.Number == 3).exists(_.benefitRecipient == driver.Faction)) {
val boosted = Math.round(vehicle.MaxHealth * 1.1).toInt
vehicle.MaxHealth = boosted
vehicle.Health = boosted
}
temp = Some(order)
val result = ask(pad.Zone.Transport, Zone.Vehicle.Spawn(vehicle))

View file

@ -58,7 +58,7 @@ trait RepairableEntity extends Repairable {
*/
protected def CanPerformRepairs(target: Repairable.Target, player: Player, item: Tool): Boolean = {
val definition = target.Definition
definition.Repairable && target.Health < definition.MaxHealth && (definition.RepairIfDestroyed || !target.Destroyed) &&
definition.Repairable && target.Health < target.MaxHealth && (definition.RepairIfDestroyed || !target.Destroyed) &&
(target.Faction == player.Faction || target.Faction == PlanetSideEmpire.NEUTRAL) && item.Magazine > 0 &&
player.isAlive && Vector3.Distance(target.Position, player.Position) < definition.RepairDistance
}

View file

@ -56,7 +56,8 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
import net.psforever.objects.vital.prop.DamageWithPosition
import net.psforever.objects.vital.Vitality
import net.psforever.objects.zones.blockmap.{BlockMap, SectorPopulation}
import net.psforever.packet.game.PropertyOverrideMessage
import net.psforever.packet.game.EmpireBenefitsMessage.{ZoneBenefit, ZoneLock, ZoneLockBenefit, ZoneLockZone}
import net.psforever.packet.game.{EmpireBenefitsMessage, PropertyOverrideMessage}
import net.psforever.services.Service
import net.psforever.zones.Zones
@ -682,11 +683,15 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
if (perks.values.forall(_.isEmpty)) {/*do nothing*/}
else {
val msg = PropertyOverrideMessage(List(PropertyOverrideMessage.GamePropertyScope(0, List(PropertyOverrideMessage.GamePropertyTarget(343,
val overrideMsg = PropertyOverrideMessage(List(PropertyOverrideMessage.GamePropertyScope(0, List(PropertyOverrideMessage.GamePropertyTarget(343,
List(PropertyOverrideMessage.GameProperty("purchase_exempt_vs", perks(PlanetSideEmpire.VS)),
PropertyOverrideMessage.GameProperty("purchase_exempt_tr", perks(PlanetSideEmpire.TR)),
PropertyOverrideMessage.GameProperty("purchase_exempt_nc", perks(PlanetSideEmpire.NC))))))))
building.Actor ! BuildingActor.HomeLockBenefits(msg)
building.Actor ! BuildingActor.HomeLockBenefits(overrideMsg)
}
val benefitMsg = BuildEmpireBenefits()
if (benefitMsg.zoneLocks.nonEmpty) {
building.Actor ! BuildingActor.HomeLockBenefits(benefitMsg)
}
}
@ -716,12 +721,71 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
if (perks.values.forall(_.isEmpty)) {/*do nothing*/}
else {
val msg = PropertyOverrideMessage(List(PropertyOverrideMessage.GamePropertyScope(0, List(PropertyOverrideMessage.GamePropertyTarget(343,
val overrideMsg = PropertyOverrideMessage(List(PropertyOverrideMessage.GamePropertyScope(0, List(PropertyOverrideMessage.GamePropertyTarget(343,
List(PropertyOverrideMessage.GameProperty("purchase_exempt_vs", perks(PlanetSideEmpire.VS)),
PropertyOverrideMessage.GameProperty("purchase_exempt_tr", perks(PlanetSideEmpire.TR)),
PropertyOverrideMessage.GameProperty("purchase_exempt_nc", perks(PlanetSideEmpire.NC))))))))
PlayerControl.sendResponse(player.Zone, player.Name, msg)
PlayerControl.sendResponse(player.Zone, player.Name, overrideMsg)
}
val benefitMsg = BuildEmpireBenefits()
if (benefitMsg.zoneLocks.nonEmpty) {
PlayerControl.sendResponse(player.Zone, player.Name, benefitMsg)
}
}
def BuildEmpireBenefits(): EmpireBenefitsMessage = {
val locks = scala.collection.mutable.ArrayBuffer[ZoneLock]()
val benefits = scala.collection.mutable.ArrayBuffer[ZoneBenefit]()
val homeSets: Map[PlanetSideEmpire.Value, Set[Int]] = Map(
PlanetSideEmpire.TR -> Set(1, 2),
PlanetSideEmpire.VS -> Set(5, 6),
PlanetSideEmpire.NC -> Set(7, 10)
)
val benefitOfZones: Map[Int, Int] = Map(
3 -> 6, // Cyssor gives benefit 6 (+10% armor bonus to vehicles)
4 -> 1, // Ishundar gives benefit 1 (vehicle shields)
9 -> 3 // Searhus gives benefit 3 (faster respawn)
)
val homePerkBenefits: Map[PlanetSideEmpire.Value, Int] = Map(
PlanetSideEmpire.TR -> 7,
PlanetSideEmpire.NC -> 8,
PlanetSideEmpire.VS -> 9
)
def isLockedBy(homeSet: Set[Int], empire: PlanetSideEmpire.Value): Boolean =
Zones.zones.filter(z => homeSet.contains(z.Number)).forall(_.benefitRecipient == empire)
// home zone perks
homeSets.foreach { case (owner, set) =>
PlanetSideEmpire.values.filterNot(_ == PlanetSideEmpire.NEUTRAL).foreach { empire =>
if (owner != empire && isLockedBy(set, empire)) {
locks += ZoneLock(empire, s"lock-${owner.toString.toLowerCase}-homes")
benefits += ZoneBenefit(empire, ZoneLockBenefit(homePerkBenefits(owner)))
}
}
}
benefitOfZones.foreach { case (zoneNum, benefitId) =>
Zones.zones.find(_.Number == zoneNum).foreach { z =>
z.benefitRecipient match {
case PlanetSideEmpire.NEUTRAL =>
//nothing
case empire =>
locks += ZoneLock(empire, s"lock-z$zoneNum")
benefits += ZoneBenefit(empire, ZoneLockBenefit(benefitId))
}
}
}
// all four islands together give benefit 4 (vehicle repair)
val islandZones: Set[Int] = Set(29, 30, 31, 32)
val islandBenefit: Int = 4
PlanetSideEmpire.values.filterNot(_ == PlanetSideEmpire.NEUTRAL).foreach { empire =>
if (isLockedBy(islandZones, empire)) {
locks += ZoneLock(empire, ZoneLockZone.i1_i2_i3_i4)
benefits += ZoneBenefit(empire, ZoneLockBenefit(islandBenefit))
}
}
EmpireBenefitsMessage(locks.toVector, benefits.toVector)
}
}

View file

@ -557,7 +557,7 @@ object GamePacketOpcode extends Enumeration {
case 0xd4 => game.GenericObjectActionAtPositionMessage.decode
case 0xd5 => game.PropertyOverrideMessage.decode
case 0xd6 => game.WarpgateLinkOverrideMessage.decode
case 0xd7 => noDecoder(EmpireBenefitsMessage)
case 0xd7 => game.EmpireBenefitsMessage.decode
// 0xd8
case 0xd8 => noDecoder(ForceEmpireMessage)
case 0xd9 => game.BroadcastWarpgateUpdateMessage.decode

View file

@ -0,0 +1,110 @@
// Copyright (c) 2025 PSForever
package net.psforever.packet.game
import net.psforever.packet.game.EmpireBenefitsMessage.{ZoneBenefit, ZoneLock}
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
import net.psforever.types.PlanetSideEmpire
import scodec.Codec
import scodec.codecs._
import scala.language.implicitConversions
/**
* EmpireBenefitsMessage
*
* zoneLocks gives the client information about which empire locks what continent.
* This produces a chat message.
* zoneBenefits tells the client what empire has which benefits enabled.
* This has to match zoneLocks to work properly.
*/
final case class EmpireBenefitsMessage(
zoneLocks: Vector[ZoneLock],
zoneBenefits: Vector[ZoneBenefit]
) extends PlanetSideGamePacket {
type Packet = EmpireBenefitsMessage
def opcode = GamePacketOpcode.EmpireBenefitsMessage
def encode = EmpireBenefitsMessage.encode(this)
}
object EmpireBenefitsMessage extends Marshallable[EmpireBenefitsMessage] {
/**
* ZoneLockZone
*
* Available Types of Zones
*
* These zones can be used to notify the client of a lock.
*/
object ZoneLockZone extends Enumeration {
type Type = String
val i1: ZoneLockZone.Value = Value("lock-i1") // Extinction Continental Lock
val i2: ZoneLockZone.Value = Value("lock-i2") // Ascension Continental Lock
val i3: ZoneLockZone.Value = Value("lock-i3") // Desolation Continental Lock
val i4: ZoneLockZone.Value = Value("lock-i4") // Nexus Continental Lock
val i1_i2_i3_i4: ZoneLockZone.Value = Value("lock-i1-i2-i3-i4") // Oshur Cluster Lock
val z3: ZoneLockZone.Value = Value("lock-z3") // Cyssor Continental Lock
val z4: ZoneLockZone.Value = Value("lock-z4") // Ishundar Continental Lock
val z9: ZoneLockZone.Value = Value("lock-z9") // Searhus Continental Lock
val tr_homes: ZoneLockZone.Value = Value("lock-tr-homes") // TR Home Continent Lock
val nc_homes: ZoneLockZone.Value = Value("lock-nc-homes") // NC Home Continent Lock
val vs_homes: ZoneLockZone.Value = Value("lock-vs-homes") // VS Home Continent Lock
implicit def valueToType(v: ZoneLockZone.Value): Type = v.toString
implicit val codec: Codec[Type] = PacketHelpers.encodedStringAligned(6)
}
/**
* ZoneLockBenefit
*
* Available Types of Benefits
*
* Benefits 0, 2 and 5 are unknown. Benefits for i1 to i4 are unknown and mapped incorrectly here.
*/
object ZoneLockBenefit extends Enumeration {
type Type = Value
val i1: ZoneLockBenefit.Value = Value(-1) // Extinction Continental Lock
val i2: ZoneLockBenefit.Value = Value(-2) // Ascension Continental Lock
val i3: ZoneLockBenefit.Value = Value(-3) // Desolation Continental Lock
val i4: ZoneLockBenefit.Value = Value(-4) // Nexus Continental Lock
// val unk0: ZoneLockBenefit.Value = Value(0)
val z4: ZoneLockBenefit.Value = Value(1) // Ishundar Continental Lock
// val unk2: ZoneLockBenefit.Value = Value(2)
val z9: ZoneLockBenefit.Value = Value(3) // Searhus Continental Lock
val i1_i2_i3_i4: ZoneLockBenefit.Value = Value(4) // Oshur Cluster Lock
// val unk5: ZoneLockBenefit.Value = Value(5)
val z3: ZoneLockBenefit.Value = Value(6) // Cyssor Continental Lock
val tr_homes: ZoneLockBenefit.Value = Value(7) // TR Home Continent Lock
val nc_homes: ZoneLockBenefit.Value = Value(8) // NC Home Continent Lock
val vs_homes: ZoneLockBenefit.Value = Value(9) // VS Home Continent Lock
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uint16L)
}
final case class ZoneLock(
empire: PlanetSideEmpire.Type,
zone: ZoneLockZone.Type,
)
final case class ZoneBenefit(
empire: PlanetSideEmpire.Type,
value: ZoneLockBenefit.Type
)
private implicit val zoneLockCodec: Codec[ZoneLock] = (
("empire" | PlanetSideEmpire.codec) ::
("zone" | ZoneLockZone.codec)
).as[ZoneLock]
private implicit val zoneBenefitCodec: Codec[ZoneBenefit] = (
("empire" | PlanetSideEmpire.codec) ::
("benefit" | ZoneLockBenefit.codec)
).as[ZoneBenefit]
implicit val codec: Codec[EmpireBenefitsMessage] = (
("zoneLocks" | vectorOfN(uint32L.xmap(_.toInt, _.toLong), zoneLockCodec)) ::
("zoneBenefits" | vectorOfN(uint32L.xmap(_.toInt, _.toLong), zoneBenefitCodec))
).as[EmpireBenefitsMessage]
}

View file

@ -44,7 +44,7 @@ final case class VariantVehicleData(unk: Int) extends SpecificVehicleData(Vehicl
* -jammered - vehicles will not be jammered by setting this field<br>
* -player_guid the vehicle's (official) owner;
* a living player in the game world on the same continent as the vehicle who may mount the driver mount
* @param unk3 na
* @param boostMaxHealth vehicle gets 10% more armor from vehicle armor benefit given by Cyssor empire lock
* @param health the amount of health the vehicle has, as a percentage of a filled bar (255)
* @param unk4 na
* @param no_mount_points do not display entry points for the seats
@ -65,7 +65,7 @@ final case class VariantVehicleData(unk: Int) extends SpecificVehicleData(Vehicl
final case class VehicleData(
pos: PlacementData,
data: CommonFieldData,
unk3: Boolean,
boostMaxHealth: Boolean,
health: Int,
unk4: Boolean,
no_mount_points: Boolean,
@ -106,7 +106,7 @@ object VehicleData extends Marshallable[VehicleData] {
cloak: Boolean,
inventory: Option[InventoryData]
): VehicleData = {
VehicleData(pos, basic, unk3 = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, None, inventory)(
VehicleData(pos, basic, boostMaxHealth = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, None, inventory)(
VehicleFormat.Normal
)
}
@ -128,7 +128,7 @@ object VehicleData extends Marshallable[VehicleData] {
format: UtilityVehicleData,
inventory: Option[InventoryData]
): VehicleData = {
VehicleData(pos, basic, unk3 = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, Some(format), inventory)(
VehicleData(pos, basic, boostMaxHealth = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, Some(format), inventory)(
VehicleFormat.Utility
)
}
@ -150,7 +150,7 @@ object VehicleData extends Marshallable[VehicleData] {
format: VariantVehicleData,
inventory: Option[InventoryData]
): VehicleData = {
VehicleData(pos, basic, unk3 = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, Some(format), inventory)(
VehicleData(pos, basic, boostMaxHealth = false, health, unk4 = false, no_mount_points = false, driveState, unk5 = false, unk6 = false, cloak = cloak, Some(format), inventory)(
VehicleFormat.Variant
)
}

View file

@ -0,0 +1,182 @@
// Copyright (c) 2025 PSForever
package game
import net.psforever.packet._
import net.psforever.packet.game.EmpireBenefitsMessage
import net.psforever.packet.game.EmpireBenefitsMessage.{ZoneBenefit, ZoneLock, ZoneLockBenefit, ZoneLockZone}
import net.psforever.types.PlanetSideEmpire
import org.specs2.mutable._
import scodec.bits._
class EmpireBenefitsMessageTest extends Specification {
val sample1: ByteVector = ByteVector.fromValidHex(
"d7" + // header
"04000000" + // count uint32L
"21c06c6f636b2d7a3321c06c6f636b2d7a3464006c6f636b2d69312d69322d69332d6934a1c06c6f636b2d7a39" +
"04000000" + // count uint32L
"004000600410020300"
)
val sample2: ByteVector = ByteVector.fromValidHex(
"d7" +
"05000000 23406c6f636b2d76732d686f6d657321c06c6f636b2d7a3321c06c6f636b2d7a3461c06c6f636b2d7a3964006c6f636b2d69312d69322d69332d6934" +
"05000000 004000600024010300410000"
)
val sample3: ByteVector = ByteVector.fromValidHex(
"d7" +
"05000000 21c06c6f636b2d7a3321c06c6f636b2d7a3423406c6f636b2d6e632d686f6d657361c06c6f636b2d7a39a4006c6f636b2d69312d69322d69332d6934" +
"05000000 004000600020010300810000"
)
val sample4: ByteVector = ByteVector.fromValidHex(
"d7" +
"06000000 a3406c6f636b2d6e632d686f6d6573a3406c6f636b2d74722d686f6d6573a1c06c6f636b2d7a33a1c06c6f636b2d7a34a1c06c6f636b2d7a39a4006c6f636b2d69312d69322d69332d6934" +
"06000000 80402030081002060081c0208000"
)
private val sample1_expectedLocks = Vector(
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z3),
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z4),
ZoneLock(PlanetSideEmpire.NC, ZoneLockZone.i1_i2_i3_i4),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.z9)
)
private val sample1_expectedBenefits = Vector(
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z4),
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z3),
ZoneBenefit(PlanetSideEmpire.NC, ZoneLockBenefit.i1_i2_i3_i4),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.z9)
)
private val sample2_expectedLocks = Vector(
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.vs_homes),
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z3),
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z4),
ZoneLock(PlanetSideEmpire.NC, ZoneLockZone.z9),
ZoneLock(PlanetSideEmpire.NC, ZoneLockZone.i1_i2_i3_i4)
)
private val sample2_expectedBenefits = Vector(
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z4),
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z3),
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.vs_homes),
ZoneBenefit(PlanetSideEmpire.NC, ZoneLockBenefit.z9),
ZoneBenefit(PlanetSideEmpire.NC, ZoneLockBenefit.i1_i2_i3_i4)
)
private val sample3_expectedLocks = Vector(
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z3),
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.z4),
ZoneLock(PlanetSideEmpire.TR, ZoneLockZone.nc_homes),
ZoneLock(PlanetSideEmpire.NC, ZoneLockZone.z9),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.i1_i2_i3_i4)
)
private val sample3_expectedBenefits = Vector(
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z4),
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.z3),
ZoneBenefit(PlanetSideEmpire.TR, ZoneLockBenefit.nc_homes),
ZoneBenefit(PlanetSideEmpire.NC, ZoneLockBenefit.z9),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.i1_i2_i3_i4)
)
private val sample4_expectedLocks = Vector(
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.nc_homes),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.tr_homes),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.z3),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.z4),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.z9),
ZoneLock(PlanetSideEmpire.VS, ZoneLockZone.i1_i2_i3_i4)
)
private val sample4_expectedBenefits = Vector(
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.z4),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.z9),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.i1_i2_i3_i4),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.z3),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.tr_homes),
ZoneBenefit(PlanetSideEmpire.VS, ZoneLockBenefit.nc_homes)
)
"decode sample1" in {
PacketCoding.decodePacket(sample1).require match {
case EmpireBenefitsMessage(a, b) =>
a mustEqual sample1_expectedLocks
b mustEqual sample1_expectedBenefits
case _ =>
ko
}
}
"encode sample1" in {
val msg = EmpireBenefitsMessage(
zoneLocks = sample1_expectedLocks,
zoneBenefits = sample1_expectedBenefits
)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
pkt mustEqual sample1
}
"decode sample2" in {
PacketCoding.decodePacket(sample2).require match {
case EmpireBenefitsMessage(a, b) =>
a mustEqual sample2_expectedLocks
b mustEqual sample2_expectedBenefits
case _ =>
ko
}
}
"encode sample2" in {
val msg = EmpireBenefitsMessage(
zoneLocks = sample2_expectedLocks,
zoneBenefits = sample2_expectedBenefits
)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
pkt mustEqual sample2
}
"decode sample3" in {
PacketCoding.decodePacket(sample3).require match {
case EmpireBenefitsMessage(a, b) =>
a mustEqual sample3_expectedLocks
b mustEqual sample3_expectedBenefits
case _ =>
ko
}
}
"encode sample3" in {
val msg = EmpireBenefitsMessage(
zoneLocks = sample3_expectedLocks,
zoneBenefits = sample3_expectedBenefits
)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
pkt mustEqual sample3
}
"decode sample4" in {
PacketCoding.decodePacket(sample4).require match {
case EmpireBenefitsMessage(a, b) =>
a mustEqual sample4_expectedLocks
b mustEqual sample4_expectedBenefits
case _ =>
ko
}
}
"encode sample4" in {
val msg = EmpireBenefitsMessage(
zoneLocks = sample4_expectedLocks,
zoneBenefits = sample4_expectedBenefits
)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
pkt mustEqual sample4
}
}

View file

@ -39,7 +39,7 @@ class MountedVehiclesTest extends Specification {
vdata.no_mount_points mustEqual false
vdata.driveState mustEqual DriveState.Mobile
vdata.cloak mustEqual false
vdata.unk3 mustEqual false
vdata.boostMaxHealth mustEqual false
vdata.unk4 mustEqual false
vdata.unk5 mustEqual false
vdata.unk6 mustEqual false

View file

@ -36,7 +36,7 @@ class UtilityVehiclesTest extends Specification {
ant.driveState mustEqual DriveState.Mobile
ant.health mustEqual 255
ant.cloak mustEqual false
ant.unk3 mustEqual false
ant.boostMaxHealth mustEqual false
ant.unk4 mustEqual false
ant.unk5 mustEqual false
ant.unk6 mustEqual false
@ -67,7 +67,7 @@ class UtilityVehiclesTest extends Specification {
ams.vehicle_format_data mustEqual Some(UtilityVehicleData(60))
ams.health mustEqual 236
ams.cloak mustEqual true
ams.unk3 mustEqual false
ams.boostMaxHealth mustEqual false
ams.unk4 mustEqual false
ams.unk5 mustEqual false
ams.unk6 mustEqual true
@ -120,7 +120,7 @@ class UtilityVehiclesTest extends Specification {
case _ =>
ko
}
ams.unk3 mustEqual false
ams.boostMaxHealth mustEqual false
ams.health mustEqual 255
ams.unk4 mustEqual false
ams.no_mount_points mustEqual false
@ -320,7 +320,7 @@ class UtilityVehiclesTest extends Specification {
Some(Vector3(27.3375f, -0.78749996f, 0.1125f))
),
CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, Some(false), None, PlanetSideGUID(3087)),
unk3 = false,
boostMaxHealth = false,
health = 255,
unk4 = false,
no_mount_points = false,