diff --git a/common/src/main/scala/net/psforever/objects/AmmoBox.scala b/common/src/main/scala/net/psforever/objects/AmmoBox.scala
index 0b5e8181..624230c6 100644
--- a/common/src/main/scala/net/psforever/objects/AmmoBox.scala
+++ b/common/src/main/scala/net/psforever/objects/AmmoBox.scala
@@ -3,6 +3,7 @@ package net.psforever.objects
import net.psforever.objects.definition.AmmoBoxDefinition
import net.psforever.objects.equipment.{Ammo, Equipment}
+import net.psforever.types.PlanetSideEmpire
class AmmoBox(private val ammoDef : AmmoBoxDefinition,
cap : Option[Int] = None
@@ -22,6 +23,8 @@ class AmmoBox(private val ammoDef : AmmoBoxDefinition,
def Definition : AmmoBoxDefinition = ammoDef
+ override def Faction_=(fact : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = Faction
+
override def toString : String = {
AmmoBox.toString(this)
}
diff --git a/common/src/main/scala/net/psforever/objects/Avatar.scala b/common/src/main/scala/net/psforever/objects/Avatar.scala
index 9452a6a6..1307ee58 100644
--- a/common/src/main/scala/net/psforever/objects/Avatar.scala
+++ b/common/src/main/scala/net/psforever/objects/Avatar.scala
@@ -3,8 +3,9 @@ package net.psforever.objects
import net.psforever.objects.avatar.DeployableToolbox
import net.psforever.objects.definition.{AvatarDefinition, ImplantDefinition}
-import net.psforever.objects.equipment.EquipmentSize
+import net.psforever.objects.equipment.{EquipmentSize, EquipmentSlot}
import net.psforever.objects.loadouts.Loadout
+import net.psforever.packet.game.objectcreate.Cosmetics
import net.psforever.types._
import scala.annotation.tailrec
@@ -15,6 +16,8 @@ class Avatar(val name : String, val faction : PlanetSideEmpire.Value, val sex :
private var bep : Long = 0
/** Command Experience Points */
private var cep : Long = 0
+ /** Cosmetics **/
+ private var pStyle : Option[Cosmetics] = None
/** Certifications */
private val certs : mutable.Set[CertificationType.Value] = mutable.Set[CertificationType.Value]()
/** Implants
@@ -56,6 +59,13 @@ class Avatar(val name : String, val faction : PlanetSideEmpire.Value, val sex :
CEP
}
+ def PersonalStyleFeatures : Option[Cosmetics] = pStyle
+
+ def PersonalStyleFeatures_=(app : Cosmetics) : Option[Cosmetics] = {
+ pStyle = Some(app)
+ pStyle
+ }
+
/**
* Retrieve the three implant slots for this player.
* @return an `Array` of `ImplantSlot` objects
@@ -166,12 +176,14 @@ class Avatar(val name : String, val faction : PlanetSideEmpire.Value, val sex :
}
}
- def LoadLoadout(line : Int) : Option[Loadout] = loadouts.lift(line).getOrElse(None)
+ def LoadLoadout(line : Int) : Option[Loadout] = loadouts.lift(line).flatten
def DeleteLoadout(line : Int) : Unit = {
loadouts(line) = None
}
+ def Loadouts : Seq[(Int, Loadout)] = loadouts.zipWithIndex.collect { case(Some(loadout), index) => (index, loadout) } toSeq
+
def Locker : LockerContainer = locker
def FifthSlot : EquipmentSlot = {
diff --git a/common/src/main/scala/net/psforever/objects/BoomerTrigger.scala b/common/src/main/scala/net/psforever/objects/BoomerTrigger.scala
index dfc3fec3..bef7ea3b 100644
--- a/common/src/main/scala/net/psforever/objects/BoomerTrigger.scala
+++ b/common/src/main/scala/net/psforever/objects/BoomerTrigger.scala
@@ -2,5 +2,8 @@
package net.psforever.objects
import net.psforever.objects.equipment.RemoteUnit
+import net.psforever.types.PlanetSideEmpire
-class BoomerTrigger extends SimpleItem(GlobalDefinitions.boomer_trigger) with RemoteUnit
+class BoomerTrigger extends SimpleItem(GlobalDefinitions.boomer_trigger) with RemoteUnit {
+ override def Faction_=(fact : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = Faction
+}
diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
index f777096c..ef41576d 100644
--- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
+++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
@@ -17,8 +17,8 @@ import net.psforever.objects.serverobject.tube.SpawnTubeDefinition
import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition
import net.psforever.objects.serverobject.turret.{TurretDefinition, TurretUpgrade}
import net.psforever.objects.vehicles.{DestroyedVehicle, SeatArmorRestriction, UtilityType}
-import net.psforever.objects.vital.{DamageType, StandardResolutions}
-import net.psforever.types.{CertificationType, PlanetSideEmpire, Vector3}
+import net.psforever.objects.vital.{DamageType, StandardMaxDamage, StandardResolutions}
+import net.psforever.types.{CertificationType, ExoSuitType, PlanetSideEmpire, Vector3}
import scala.collection.mutable
import scala.concurrent.duration._
@@ -29,6 +29,71 @@ object GlobalDefinitions {
*/
val avatar = new AvatarDefinition(121)
/*
+ Exo-suits
+ */
+ val Standard = ExoSuitDefinition(ExoSuitType.Standard)
+ Standard.Name = "standard"
+ Standard.MaxArmor = 50
+ Standard.InventoryScale = InventoryTile.Tile96
+ Standard.InventoryOffset = 6
+ Standard.Holster(0, EquipmentSize.Pistol)
+ Standard.Holster(2, EquipmentSize.Rifle)
+ Standard.Holster(4, EquipmentSize.Melee)
+ Standard.ResistanceDirectHit = 4
+ Standard.ResistanceSplash = 15
+ Standard.ResistanceAggravated = 8
+
+ val Agile = ExoSuitDefinition(ExoSuitType.Agile)
+ Agile.Name = "agile"
+ Agile.MaxArmor = 100
+ Agile.InventoryScale = InventoryTile.Tile99
+ Agile.InventoryOffset = 6
+ Agile.Holster(0, EquipmentSize.Pistol)
+ Agile.Holster(1, EquipmentSize.Pistol)
+ Agile.Holster(2, EquipmentSize.Rifle)
+ Agile.Holster(4, EquipmentSize.Melee)
+ Agile.ResistanceDirectHit = 6
+ Agile.ResistanceSplash = 25
+ Agile.ResistanceAggravated = 10
+
+ val Reinforced = ExoSuitDefinition(ExoSuitType.Reinforced)
+ Reinforced.Name = "reinforced"
+ Reinforced.Permissions = List(CertificationType.ReinforcedExoSuit)
+ Reinforced.MaxArmor = 200
+ Reinforced.InventoryScale = InventoryTile.Tile1209
+ Reinforced.InventoryOffset = 6
+ Reinforced.Holster(0, EquipmentSize.Pistol)
+ Reinforced.Holster(1, EquipmentSize.Pistol)
+ Reinforced.Holster(2, EquipmentSize.Rifle)
+ Reinforced.Holster(3, EquipmentSize.Rifle)
+ Reinforced.Holster(4, EquipmentSize.Melee)
+ Reinforced.ResistanceDirectHit = 10
+ Reinforced.ResistanceSplash = 35
+ Reinforced.ResistanceAggravated = 12
+
+ val Infiltration = ExoSuitDefinition(ExoSuitType.Infiltration)
+ Infiltration.Name = "infiltration_suit"
+ Infiltration.Permissions = List(CertificationType.InfiltrationSuit)
+ Infiltration.MaxArmor = 0
+ Infiltration.InventoryScale = InventoryTile.Tile66
+ Infiltration.InventoryOffset = 6
+ Infiltration.Holster(0, EquipmentSize.Pistol)
+ Infiltration.Holster(4, EquipmentSize.Melee)
+
+ val MAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
+ MAX.Permissions = List(CertificationType.AIMAX,CertificationType.AVMAX, CertificationType.AAMAX, CertificationType.UniMAX)
+ MAX.MaxArmor = 650
+ MAX.InventoryScale = InventoryTile.Tile1612
+ MAX.InventoryOffset = 6
+ MAX.Holster(0, EquipmentSize.Max)
+ MAX.Holster(4, EquipmentSize.Melee)
+ MAX.Subtract.Damage1 = -2
+ MAX.ResistanceDirectHit = 6
+ MAX.ResistanceSplash = 35
+ MAX.ResistanceAggravated = 10
+ MAX.Damage = StandardMaxDamage
+ MAX.Model = StandardResolutions.Max
+ /*
Implants
*/
val advanced_regen = ImplantDefinition(0)
@@ -880,37 +945,44 @@ object GlobalDefinitions {
/*
Miscellaneous
*/
- val order_terminal = new OrderTerminalDefinition
val ams_respawn_tube = new SpawnTubeDefinition(49)
+ val matrix_terminala = new MatrixTerminalDefinition(517)
+
+ val matrix_terminalb = new MatrixTerminalDefinition(518)
+
val matrix_terminalc = new MatrixTerminalDefinition(519)
- val order_terminala = new OrderTerminalABDefinition(613)
+ val spawn_terminal = new MatrixTerminalDefinition(812)
- val order_terminalb = new OrderTerminalABDefinition(614)
+ val order_terminal = new OrderTerminalDefinition(612)
- val cert_terminal = new CertTerminalDefinition
+ val order_terminala = new OrderTerminalDefinition(613)
+
+ val order_terminalb = new OrderTerminalDefinition(614)
+
+ val cert_terminal = new OrderTerminalDefinition(171)
val implant_terminal_mech = new ImplantTerminalMechDefinition
- val implant_terminal_interface = new ImplantTerminalInterfaceDefinition
+ val implant_terminal_interface = new OrderTerminalDefinition(409)
- val ground_vehicle_terminal = new GroundVehicleTerminalDefinition
+ val ground_vehicle_terminal = new OrderTerminalDefinition(386)
- val air_vehicle_terminal = new AirVehicleTerminalDefinition
+ val air_vehicle_terminal = new OrderTerminalDefinition(43)
- val dropship_vehicle_terminal = new DropshipVehicleTerminalDefinition
+ val dropship_vehicle_terminal = new OrderTerminalDefinition(263)
- val vehicle_terminal_combined = new VehicleTerminalCombinedDefinition
+ val vehicle_terminal_combined = new OrderTerminalDefinition(952)
- val spawn_terminal = new MatrixTerminalDefinition(812)
+ val bfr_terminal = new OrderTerminalDefinition(143)
val respawn_tube = new SpawnTubeDefinition(732)
val respawn_tube_tower = new SpawnTubeDefinition(733)
- val teleportpad_terminal = new TeleportPadTerminalDefinition
+ val teleportpad_terminal = new OrderTerminalDefinition(853)
val adv_med_terminal = new MedicalTerminalDefinition(38)
@@ -944,13 +1016,13 @@ object GlobalDefinitions {
val lodestar_repair_terminal = new MedicalTerminalDefinition(461)
- val multivehicle_rearm_terminal = new _OrderTerminalDefinition(576)
+ val multivehicle_rearm_terminal = new OrderTerminalDefinition(576)
- val bfr_rearm_terminal = new _OrderTerminalDefinition(142)
+ val bfr_rearm_terminal = new OrderTerminalDefinition(142)
- val air_rearm_terminal = new _OrderTerminalDefinition(42)
+ val air_rearm_terminal = new OrderTerminalDefinition(42)
- val ground_rearm_terminal = new _OrderTerminalDefinition(384)
+ val ground_rearm_terminal = new OrderTerminalDefinition(384)
val manned_turret = new TurretDefinition(480)
initMiscellaneous()
@@ -1338,6 +1410,68 @@ object GlobalDefinitions {
super_staminakit.Name = "super_staminakit"
}
+ /**
+ * Initialize `ExoSuitType` globals.
+ */
+ private def init_exosuit() : Unit = {
+ Standard.Name = "standard"
+ Standard.MaxArmor = 50
+ Standard.InventoryScale = InventoryTile.Tile96
+ Standard.InventoryOffset = 6
+ Standard.Holster(0, EquipmentSize.Pistol)
+ Standard.Holster(2, EquipmentSize.Rifle)
+ Standard.Holster(4, EquipmentSize.Melee)
+ Standard.ResistanceDirectHit = 4
+ Standard.ResistanceSplash = 15
+ Standard.ResistanceAggravated = 8
+
+ Agile.Name = "lite_armor"
+ Agile.MaxArmor = 100
+ Agile.InventoryScale = InventoryTile.Tile99
+ Agile.InventoryOffset = 6
+ Agile.Holster(0, EquipmentSize.Pistol)
+ Agile.Holster(1, EquipmentSize.Pistol)
+ Agile.Holster(2, EquipmentSize.Rifle)
+ Agile.Holster(4, EquipmentSize.Melee)
+ Agile.ResistanceDirectHit = 6
+ Agile.ResistanceSplash = 25
+ Agile.ResistanceAggravated = 10
+
+ Reinforced.Name = "med_armor"
+ Reinforced.Permissions = List(CertificationType.ReinforcedExoSuit)
+ Reinforced.MaxArmor = 200
+ Reinforced.InventoryScale = InventoryTile.Tile1209
+ Reinforced.InventoryOffset = 6
+ Reinforced.Holster(0, EquipmentSize.Pistol)
+ Reinforced.Holster(1, EquipmentSize.Pistol)
+ Reinforced.Holster(2, EquipmentSize.Rifle)
+ Reinforced.Holster(3, EquipmentSize.Rifle)
+ Reinforced.Holster(4, EquipmentSize.Melee)
+ Reinforced.ResistanceDirectHit = 10
+ Reinforced.ResistanceSplash = 35
+ Reinforced.ResistanceAggravated = 12
+
+ Infiltration.Name = "infiltration_suit"
+ Infiltration.Permissions = List(CertificationType.InfiltrationSuit)
+ Infiltration.MaxArmor = 0
+ Infiltration.InventoryScale = InventoryTile.Tile66
+ Infiltration.InventoryOffset = 6
+ Infiltration.Holster(0, EquipmentSize.Pistol)
+ Infiltration.Holster(4, EquipmentSize.Melee)
+
+ MAX.Permissions = List(CertificationType.AIMAX,CertificationType.AVMAX, CertificationType.AAMAX, CertificationType.UniMAX)
+ MAX.MaxArmor = 650
+ MAX.InventoryScale = InventoryTile.Tile1612
+ MAX.InventoryOffset = 6
+ MAX.Holster(0, EquipmentSize.Max)
+ MAX.Holster(4, EquipmentSize.Melee)
+ MAX.Subtract.Damage1 = -2
+ MAX.ResistanceDirectHit = 6
+ MAX.ResistanceSplash = 35
+ MAX.ResistanceAggravated = 10
+ MAX.Damage = StandardMaxDamage
+ MAX.Model = StandardResolutions.Max
+ }
/**
* Initialize `AmmoBoxDefinition` globals.
*/
@@ -5578,7 +5712,7 @@ object GlobalDefinitions {
deployable_shield_generator.MaxHealth = 1700
deployable_shield_generator.DeployTime = Duration.create(6000, "ms")
deployable_shield_generator.Model = StandardResolutions.ComplexDeployables
-
+
router_telepad_deployable.Name = "router_telepad_deployable"
router_telepad_deployable.MaxHealth = 100
router_telepad_deployable.DeployTime = Duration.create(1, "ms")
@@ -5595,6 +5729,67 @@ object GlobalDefinitions {
* Initialize `Miscellaneous` globals.
*/
private def initMiscellaneous() : Unit = {
+ matrix_terminala.Name = "matrix_terminala"
+
+ matrix_terminalb.Name = "matrix_terminalb"
+
+ matrix_terminalc.Name = "matrix_terminalc"
+
+ spawn_terminal.Name = "spawn_terminal"
+
+ order_terminal.Name = "order_terminal"
+ order_terminal.Tab += 0 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.infantryAmmunition ++ EquipmentTerminalDefinition.infantryWeapons)
+ order_terminal.Tab += 1 -> OrderTerminalDefinition.ArmorWithAmmoPage(EquipmentTerminalDefinition.suits ++ EquipmentTerminalDefinition.maxSuits, EquipmentTerminalDefinition.maxAmmo)
+ order_terminal.Tab += 2 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.supportAmmunition ++ EquipmentTerminalDefinition.supportWeapons)
+ order_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ order_terminal.Tab += 4 -> OrderTerminalDefinition.InfantryLoadoutPage()
+ order_terminal.SellEquipmentByDefault = true
+
+ order_terminala.Name = "order_terminala"
+ order_terminala.Tab += 0 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.infantryAmmunition ++ EquipmentTerminalDefinition.infantryWeapons)
+ order_terminala.Tab += 1 -> OrderTerminalDefinition.ArmorWithAmmoPage(EquipmentTerminalDefinition.suits, EquipmentTerminalDefinition.maxAmmo)
+ order_terminala.Tab += 2 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.supportAmmunition ++ EquipmentTerminalDefinition.supportWeapons)
+ order_terminala.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ order_terminala.Tab += 4 -> OrderTerminalDefinition.InfantryLoadoutPage()
+ order_terminala.SellEquipmentByDefault = true
+
+ order_terminalb.Name = "order_terminalb"
+ order_terminalb.Tab += 0 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.infantryAmmunition ++ EquipmentTerminalDefinition.infantryWeapons)
+ order_terminalb.Tab += 1 -> OrderTerminalDefinition.ArmorWithAmmoPage(EquipmentTerminalDefinition.suits, EquipmentTerminalDefinition.maxAmmo)
+ order_terminalb.Tab += 2 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.supportAmmunition ++ EquipmentTerminalDefinition.supportWeapons)
+ order_terminalb.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ order_terminalb.Tab += 4 -> OrderTerminalDefinition.InfantryLoadoutPage()
+ order_terminalb.SellEquipmentByDefault = true
+
+ cert_terminal.Name = "cert_terminal"
+ cert_terminal.Tab += 0 -> OrderTerminalDefinition.CertificationPage(CertTerminalDefinition.certs)
+
+ implant_terminal_interface.Name = "implant_terminal_interface"
+ implant_terminal_interface.Tab += 0 -> OrderTerminalDefinition.ImplantPage(ImplantTerminalDefinition.implants)
+
+ ground_vehicle_terminal.Name = "ground_vehicle_terminal"
+ ground_vehicle_terminal.Tab += 46769 -> OrderTerminalDefinition.VehiclePage(VehicleTerminalDefinition.groundVehicles, VehicleTerminalDefinition.trunk)
+ ground_vehicle_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+
+ air_vehicle_terminal.Name = "air_vehicle_terminal"
+ air_vehicle_terminal.Tab += 46769 -> OrderTerminalDefinition.VehiclePage(VehicleTerminalDefinition.flight1Vehicles, VehicleTerminalDefinition.trunk)
+ air_vehicle_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+
+ dropship_vehicle_terminal.Name = "dropship_vehicle_terminal"
+ dropship_vehicle_terminal.Tab += 46769 -> OrderTerminalDefinition.VehiclePage(VehicleTerminalDefinition.flight1Vehicles ++ VehicleTerminalDefinition.flight2Vehicles, VehicleTerminalDefinition.trunk)
+ dropship_vehicle_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+
+ vehicle_terminal_combined.Name = "vehicle_terminal_combined"
+ vehicle_terminal_combined.Tab += 46769 -> OrderTerminalDefinition.VehiclePage(VehicleTerminalDefinition.flight1Vehicles ++ VehicleTerminalDefinition.groundVehicles, VehicleTerminalDefinition.trunk)
+ vehicle_terminal_combined.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+
+ bfr_terminal.Name = "bfr_terminal"
+ bfr_terminal.Tab += 46769 -> OrderTerminalDefinition.VehiclePage(VehicleTerminalDefinition.bfrVehicles, VehicleTerminalDefinition.trunk)
+ bfr_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+
+ teleportpad_terminal.Name = "teleportpad_terminal"
+ teleportpad_terminal.Tab += 0 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.routerTerminal)
+
adv_med_terminal.Name = "adv_med_terminal"
adv_med_terminal.Interval = 500
adv_med_terminal.HealAmount = 8
@@ -5653,20 +5848,24 @@ object GlobalDefinitions {
lodestar_repair_terminal.TargetValidation += ProximityTarget.Vehicle -> ProximityTerminalControl.Validation.RepairSilo
multivehicle_rearm_terminal.Name = "multivehicle_rearm_terminal"
- multivehicle_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
- multivehicle_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
+ multivehicle_rearm_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ multivehicle_rearm_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+ multivehicle_rearm_terminal.SellEquipmentByDefault = true //TODO ?
bfr_rearm_terminal.Name = "bfr_rearm_terminal"
- bfr_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(Map.empty[String, ()=>Equipment]) //TODO add stock to page
- bfr_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
+ bfr_rearm_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(Map.empty[String, ()=>Equipment]) //TODO add stock to page
+ bfr_rearm_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+ bfr_rearm_terminal.SellEquipmentByDefault = true //TODO ?
air_rearm_terminal.Name = "air_rearm_terminal"
- air_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
- air_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
+ air_rearm_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ air_rearm_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+ air_rearm_terminal.SellEquipmentByDefault = true //TODO ?
ground_rearm_terminal.Name = "ground_rearm_terminal"
- ground_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
- ground_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
+ ground_rearm_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
+ ground_rearm_terminal.Tab += 4 -> OrderTerminalDefinition.VehicleLoadoutPage()
+ ground_rearm_terminal.SellEquipmentByDefault = true //TODO ?
manned_turret.Name = "manned_turret"
manned_turret.MaxHealth = 3600
diff --git a/common/src/main/scala/net/psforever/objects/OffhandEquipmentSlot.scala b/common/src/main/scala/net/psforever/objects/OffhandEquipmentSlot.scala
index 0d9a5151..e6045467 100644
--- a/common/src/main/scala/net/psforever/objects/OffhandEquipmentSlot.scala
+++ b/common/src/main/scala/net/psforever/objects/OffhandEquipmentSlot.scala
@@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
-import net.psforever.objects.equipment.EquipmentSize
+import net.psforever.objects.equipment.{EquipmentSize, EquipmentSlot}
/**
* A size-checked unit of storage (or mounting) for `Equipment`.
diff --git a/common/src/main/scala/net/psforever/objects/Player.scala b/common/src/main/scala/net/psforever/objects/Player.scala
index aa5dff72..e1e015f2 100644
--- a/common/src/main/scala/net/psforever/objects/Player.scala
+++ b/common/src/main/scala/net/psforever/objects/Player.scala
@@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
-import net.psforever.objects.definition.AvatarDefinition
-import net.psforever.objects.equipment.{Equipment, EquipmentSize}
+import net.psforever.objects.definition.{AvatarDefinition, ExoSuitDefinition, SpecialExoSuitDefinition}
+import net.psforever.objects.equipment.{Equipment, EquipmentSize, EquipmentSlot}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
import net.psforever.objects.loadouts.Loadout
import net.psforever.objects.serverobject.affinity.FactionAffinity
@@ -10,6 +10,7 @@ import net.psforever.objects.vital.resistance.ResistanceProfile
import net.psforever.objects.vital.{DamageResistanceModel, Vitality}
import net.psforever.objects.zones.ZoneAware
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{Cosmetics, DetailedCharacterData, PersonalStyle}
import net.psforever.types._
import scala.annotation.tailrec
@@ -29,18 +30,18 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
private var maxHealth : Int = 100 //TODO affected by empire benefits, territory benefits, and bops
private var maxStamina : Int = 100 //does anything affect this?
- private var exosuit : ExoSuitDefinition = ExoSuitDefinition.Standard
+ private var exosuit : ExoSuitDefinition = GlobalDefinitions.Standard
private val freeHand : EquipmentSlot = new OffhandEquipmentSlot(EquipmentSize.Inventory)
private val holsters : Array[EquipmentSlot] = Array.fill[EquipmentSlot](5)(new EquipmentSlot)
private val inventory : GridInventory = GridInventory()
private var drawnSlot : Int = Player.HandsDownSlot
private var lastDrawnSlot : Int = Player.HandsDownSlot
+ private var backpackAccess : Option[PlanetSideGUID] = None
private var facingYawUpper : Float = 0f
private var crouching : Boolean = false
private var jumping : Boolean = false
private var cloaked : Boolean = false
- private var backpackAccess : Option[PlanetSideGUID] = None
private var vehicleSeated : Option[PlanetSideGUID] = None
private var vehicleOwned : Option[PlanetSideGUID] = None
@@ -347,7 +348,71 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
Cloaked
}
- private var usingSpecial : (SpecialExoSuitDefinition.Mode.Value)=>SpecialExoSuitDefinition.Mode.Value = DefaultUsingSpecial
+ def PersonalStyleFeatures : Option[Cosmetics] = core.PersonalStyleFeatures
+
+ def AddToPersonalStyle(value : PersonalStyle.Value) : (Option[Cosmetics], Option[Cosmetics]) = {
+ val original = core.PersonalStyleFeatures
+ if(DetailedCharacterData.isBR24(core.BEP)) {
+ core.PersonalStyleFeatures = original match {
+ case Some(cosmetic) =>
+ cosmetic + value
+ case None =>
+ Cosmetics(value)
+ }
+ (original, core.PersonalStyleFeatures)
+ }
+ else {
+ (None, None)
+ }
+ }
+
+ def RemoveFromPersonalStyle(value : PersonalStyle.Value) : (Option[Cosmetics], Option[Cosmetics]) = {
+ val original = core.PersonalStyleFeatures
+ original match {
+ case Some(cosmetics) =>
+ (original, core.PersonalStyleFeatures = cosmetics - value)
+ case None =>
+ (None, None)
+ }
+ }
+
+ private def BasicFeatureToggle(feature : PersonalStyle.Value) : (Option[Cosmetics], Option[Cosmetics]) = core.PersonalStyleFeatures match {
+ case Some(c : Cosmetics) =>
+ if(c.Styles.contains(feature)) {
+ RemoveFromPersonalStyle(feature)
+ }
+ else {
+ AddToPersonalStyle(feature)
+ }
+ case None =>
+ AddToPersonalStyle(feature)
+ }
+
+ def ToggleHelmet : (Option[Cosmetics], Option[Cosmetics]) = BasicFeatureToggle(PersonalStyle.NoHelmet)
+
+ def ToggleShades : (Option[Cosmetics], Option[Cosmetics]) = BasicFeatureToggle(PersonalStyle.Sunglasses)
+
+ def ToggleEarpiece : (Option[Cosmetics], Option[Cosmetics]) = BasicFeatureToggle(PersonalStyle.Earpiece)
+
+ def ToggleHat : (Option[Cosmetics], Option[Cosmetics]) = {
+ core.PersonalStyleFeatures match {
+ case Some(c : Cosmetics) =>
+ if(c.Styles.contains(PersonalStyle.BrimmedCap)) {
+ (RemoveFromPersonalStyle(PersonalStyle.BrimmedCap)._1,
+ AddToPersonalStyle(PersonalStyle.Beret)._2)
+ }
+ else if(c.Styles.contains(PersonalStyle.Beret)) {
+ RemoveFromPersonalStyle(PersonalStyle.Beret)
+ }
+ else {
+ AddToPersonalStyle(PersonalStyle.BrimmedCap)
+ }
+ case None =>
+ AddToPersonalStyle(PersonalStyle.BrimmedCap)
+ }
+ }
+
+ private var usingSpecial : SpecialExoSuitDefinition.Mode.Value=>SpecialExoSuitDefinition.Mode.Value = DefaultUsingSpecial
private var gettingSpecial : ()=>SpecialExoSuitDefinition.Mode.Value = DefaultGettingSpecial
diff --git a/common/src/main/scala/net/psforever/objects/Vehicle.scala b/common/src/main/scala/net/psforever/objects/Vehicle.scala
index 3057d4db..c552177b 100644
--- a/common/src/main/scala/net/psforever/objects/Vehicle.scala
+++ b/common/src/main/scala/net/psforever/objects/Vehicle.scala
@@ -3,7 +3,7 @@ package net.psforever.objects
import akka.actor.ActorRef
import net.psforever.objects.definition.VehicleDefinition
-import net.psforever.objects.equipment.{Equipment, EquipmentSize}
+import net.psforever.objects.equipment.{Equipment, EquipmentSize, EquipmentSlot}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile}
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.serverobject.PlanetSideServerObject
diff --git a/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/ExoSuitDefinition.scala
similarity index 60%
rename from common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala
rename to common/src/main/scala/net/psforever/objects/definition/ExoSuitDefinition.scala
index e96e4a9d..7cc43ad4 100644
--- a/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/ExoSuitDefinition.scala
@@ -1,24 +1,27 @@
// Copyright (c) 2017 PSForever
-package net.psforever.objects
+package net.psforever.objects.definition
+import net.psforever.objects.GlobalDefinitions
import net.psforever.objects.equipment.EquipmentSize
import net.psforever.objects.inventory.InventoryTile
import net.psforever.objects.vital._
import net.psforever.objects.vital.resistance.ResistanceProfileMutators
-import net.psforever.types.ExoSuitType
+import net.psforever.types.{CertificationType, ExoSuitType}
/**
* A definition for producing the personal armor the player wears.
* Players are influenced by the exo-suit they wear in a variety of ways, with speed and available equipment slots being major differences.
* @param suitType the `Enumeration` corresponding to this exo-suit
*/
-class ExoSuitDefinition(private val suitType : ExoSuitType.Value) extends ResistanceProfileMutators
+class ExoSuitDefinition(private val suitType : ExoSuitType.Value) extends BasicDefinition
+ with ResistanceProfileMutators
with DamageResistanceModel {
- protected var permission : Int = 0 //TODO certification type?
+ protected var permissions : List[CertificationType.Value] = List.empty
protected var maxArmor : Int = 0
protected val holsters : Array[EquipmentSize.Value] = Array.fill[EquipmentSize.Value](5)(EquipmentSize.Blocked)
protected var inventoryScale : InventoryTile = InventoryTile.Tile11 //override with custom InventoryTile
protected var inventoryOffset : Int = 0
+ Name = "exo-suit"
Damage = StandardInfantryDamage
Resistance = StandardInfantryResistance
Model = StandardResolutions.Infantry
@@ -67,10 +70,19 @@ class ExoSuitDefinition(private val suitType : ExoSuitType.Value) extends Resist
}
}
+ def Permissions : List[CertificationType.Value] = permissions
+
+ def Permissions_=(certs : List[CertificationType.Value]) : List[CertificationType.Value] = {
+ permissions = certs
+ Permissions
+ }
+
def Use : ExoSuitDefinition = this
}
class SpecialExoSuitDefinition(private val suitType : ExoSuitType.Value) extends ExoSuitDefinition(suitType) {
+ Name = "heavy_armor"
+
private var activatedSpecial : SpecialExoSuitDefinition.Mode.Value = SpecialExoSuitDefinition.Mode.Normal
def UsingSpecial : SpecialExoSuitDefinition.Mode.Value = activatedSpecial
@@ -118,65 +130,6 @@ object SpecialExoSuitDefinition {
}
object ExoSuitDefinition {
- final val Standard = ExoSuitDefinition(ExoSuitType.Standard)
- Standard.MaxArmor = 50
- Standard.InventoryScale = InventoryTile.Tile96
- Standard.InventoryOffset = 6
- Standard.Holster(0, EquipmentSize.Pistol)
- Standard.Holster(2, EquipmentSize.Rifle)
- Standard.Holster(4, EquipmentSize.Melee)
- Standard.ResistanceDirectHit = 4
- Standard.ResistanceSplash = 15
- Standard.ResistanceAggravated = 8
-
- final val Agile = ExoSuitDefinition(ExoSuitType.Agile)
- Agile.MaxArmor = 100
- Agile.InventoryScale = InventoryTile.Tile99
- Agile.InventoryOffset = 6
- Agile.Holster(0, EquipmentSize.Pistol)
- Agile.Holster(1, EquipmentSize.Pistol)
- Agile.Holster(2, EquipmentSize.Rifle)
- Agile.Holster(4, EquipmentSize.Melee)
- Agile.ResistanceDirectHit = 6
- Agile.ResistanceSplash = 25
- Agile.ResistanceAggravated = 10
-
- final val Reinforced = ExoSuitDefinition(ExoSuitType.Reinforced)
- Reinforced.permission = 1
- Reinforced.MaxArmor = 200
- Reinforced.InventoryScale = InventoryTile.Tile1209
- Reinforced.InventoryOffset = 6
- Reinforced.Holster(0, EquipmentSize.Pistol)
- Reinforced.Holster(1, EquipmentSize.Pistol)
- Reinforced.Holster(2, EquipmentSize.Rifle)
- Reinforced.Holster(3, EquipmentSize.Rifle)
- Reinforced.Holster(4, EquipmentSize.Melee)
- Reinforced.ResistanceDirectHit = 10
- Reinforced.ResistanceSplash = 35
- Reinforced.ResistanceAggravated = 12
-
- final val Infiltration = ExoSuitDefinition(ExoSuitType.Infiltration)
- Infiltration.permission = 1
- Infiltration.MaxArmor = 0
- Infiltration.InventoryScale = InventoryTile.Tile66
- Infiltration.InventoryOffset = 6
- Infiltration.Holster(0, EquipmentSize.Pistol)
- Infiltration.Holster(4, EquipmentSize.Melee)
-
- final val MAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
- MAX.permission = 1
- MAX.MaxArmor = 650
- MAX.InventoryScale = InventoryTile.Tile1612
- MAX.InventoryOffset = 6
- MAX.Holster(0, EquipmentSize.Max)
- MAX.Holster(4, EquipmentSize.Melee)
- MAX.Subtract.Damage1 = -2
- MAX.ResistanceDirectHit = 6
- MAX.ResistanceSplash = 35
- MAX.ResistanceAggravated = 10
- MAX.Damage = StandardMaxDamage
- MAX.Model = StandardResolutions.Max
-
def apply(suitType : ExoSuitType.Value) : ExoSuitDefinition = {
new ExoSuitDefinition(suitType)
}
@@ -188,11 +141,11 @@ object ExoSuitDefinition {
*/
def Select(suit : ExoSuitType.Value) : ExoSuitDefinition = {
suit match {
- case ExoSuitType.Agile => ExoSuitDefinition.Agile.Use
- case ExoSuitType.Infiltration => ExoSuitDefinition.Infiltration.Use
- case ExoSuitType.MAX => ExoSuitDefinition.MAX.Use
- case ExoSuitType.Reinforced => ExoSuitDefinition.Reinforced.Use
- case _ => ExoSuitDefinition.Standard.Use
+ case ExoSuitType.Agile => GlobalDefinitions.Agile.Use
+ case ExoSuitType.Infiltration => GlobalDefinitions.Infiltration.Use
+ case ExoSuitType.MAX => GlobalDefinitions.MAX.Use
+ case ExoSuitType.Reinforced => GlobalDefinitions.Reinforced.Use
+ case _ => GlobalDefinitions.Standard.Use
}
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/ACEConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/ACEConverter.scala
index d45acda1..da288462 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/ACEConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/ACEConverter.scala
@@ -2,16 +2,45 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.ConstructionItem
-import net.psforever.packet.game.objectcreate.{ACEData, DetailedACEData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedConstructionToolData, HandheldData}
import scala.util.{Success, Try}
class ACEConverter extends ObjectCreateConverter[ConstructionItem]() {
- override def ConstructorData(obj : ConstructionItem) : Try[ACEData] = {
- Success(ACEData(0,0))
+ override def ConstructorData(obj : ConstructionItem) : Try[HandheldData] = {
+ Success(
+ HandheldData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
+ )
+ )
}
- override def DetailedConstructorData(obj : ConstructionItem) : Try[DetailedACEData] = {
- Success(DetailedACEData(0))
+ override def DetailedConstructorData(obj : ConstructionItem) : Try[DetailedConstructionToolData] = {
+ Success(
+ DetailedConstructionToolData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
+ )
+ )
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/AmmoBoxConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/AmmoBoxConverter.scala
index 890a9963..84a5a81b 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/AmmoBoxConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/AmmoBoxConverter.scala
@@ -2,16 +2,33 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.AmmoBox
-import net.psforever.packet.game.objectcreate.{AmmoBoxData, DetailedAmmoBoxData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedAmmoBoxData}
+import net.psforever.types.PlanetSideEmpire
import scala.util.{Success, Try}
class AmmoBoxConverter extends ObjectCreateConverter[AmmoBox] {
- override def ConstructorData(obj : AmmoBox) : Try[AmmoBoxData] = {
- Success(AmmoBoxData())
+ override def ConstructorData(obj : AmmoBox) : Try[CommonFieldData] = {
+ Success(CommonFieldData()(false))
}
override def DetailedConstructorData(obj : AmmoBox) : Try[DetailedAmmoBoxData] = {
- Success(DetailedAmmoBoxData(8, obj.Capacity))
+ Success(
+ DetailedAmmoBoxData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ obj.Capacity
+ )
+ )
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala
index 24e80263..a141529c 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala
@@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.definition.converter
-import net.psforever.objects.{EquipmentSlot, Player}
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.Player
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._
import net.psforever.types.{ExoSuitType, GrenadeState, ImplantType}
@@ -63,18 +64,22 @@ object AvatarConverter {
* @param obj the `Player` game object
* @return the resulting `CharacterAppearanceData`
*/
- def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
+ def MakeAppearanceData(obj : Player) : Int=>CharacterAppearanceData = {
val alt_model_flag : Boolean = obj.isBackpack
val aa : Int=>CharacterAppearanceA = CharacterAppearanceA(
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, obj.Voice),
- black_ops = false,
- alt_model_flag,
- false,
- None,
- jammered = false,
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alt_model_flag,
+ false,
+ None,
+ false,
+ None,
+ v5 = None,
+ PlanetSideGUID(0)
+ ),
obj.ExoSuit,
- None,
- 0,
0,
0L,
0,
@@ -108,22 +113,22 @@ object AvatarConverter {
def MakeCharacterData(obj : Player) : (Boolean,Boolean)=>CharacterData = {
val MaxArmor = obj.MaxArmor
CharacterData(
- 255 * obj.Health / obj.MaxHealth,
+ StatConverter.Health(obj.Health, obj.MaxHealth),
if(MaxArmor == 0) {
0
}
else {
- 255 * obj.Armor / MaxArmor
+ StatConverter.Health(obj.Armor, MaxArmor)
},
DressBattleRank(obj),
0,
DressCommandRank(obj),
MakeImplantEffectList(obj.Implants),
- MakeCosmetics(obj.BEP)
+ MakeCosmetics(obj)
)
}
- def MakeDetailedCharacterData(obj : Player) : (Option[Int])=>DetailedCharacterData = {
+ def MakeDetailedCharacterData(obj : Player) : Option[Int]=>DetailedCharacterData = {
val bep : Long = obj.BEP
val maxOpt : Option[Long] = if(obj.ExoSuit == ExoSuitType.MAX) { Some(0L) } else { None }
val ba : DetailedCharacterA = DetailedCharacterA(
@@ -149,9 +154,9 @@ object AvatarConverter {
0L, 0L, 0L, 0L, 0L,
Some(DCDExtra2(0, 0)),
Nil, Nil, false,
- MakeCosmetics(bep)
+ MakeCosmetics(obj)
)
- (pad_length : Option[Int]) => DetailedCharacterData(ba, bb(bep, pad_length))(pad_length)
+ pad_length : Option[Int] => DetailedCharacterData(ba, bb(bep, pad_length))(pad_length)
}
def MakeInventoryData(obj : Player) : InventoryData = {
@@ -219,8 +224,8 @@ object AvatarConverter {
* @see `ImplantEntry` in `DetailedCharacterData`
*/
private def MakeImplantEntries(obj : Player) : List[ImplantEntry] = {
- val numImplants : Int = DetailedCharacterData.numberOfImplantSlots(obj.BEP)
- val implants = obj.Implants
+ //val numImplants : Int = DetailedCharacterData.numberOfImplantSlots(obj.BEP)
+ //val implants = obj.Implants
obj.Implants.map({ case(implant, initialization, _) =>
if(initialization == 0) {
ImplantEntry(implant, None)
@@ -238,7 +243,7 @@ object AvatarConverter {
*/
private def MakeImplantEffectList(implants : Seq[(ImplantType.Value, Long, Boolean)]) : List[ImplantEffects.Value] = {
implants.collect {
- case ((implant,_,true)) =>
+ case (implant,_,true) =>
implant match {
case ImplantType.AdvancedRegen =>
ImplantEffects.RegenEffects
@@ -253,14 +258,16 @@ object AvatarConverter {
}
/**
- * Should this player be of battle rank 24 or higher, they will have a mandatory cosmetics object.
- * @param bep battle experience points
+ * Should this player be of battle rank 24 or higher, they will have a mandatory cosmetics object in their bitstream.
+ * Players that have not yet set any cosmetic personal effects will still have this field recorded as `None`
+ * but it must be represented nonetheless.
+ * @param obj the `Player` game object
* @see `Cosmetics`
* @return the `Cosmetics` options
*/
- def MakeCosmetics(bep : Long) : Option[Cosmetics] =
- if(DetailedCharacterData.isBR24(bep)) {
- Some(Cosmetics(false, false, false, false, false))
+ def MakeCosmetics(obj : Player) : Option[Cosmetics] =
+ if(DetailedCharacterData.isBR24(obj.BEP)) {
+ obj.PersonalStyleFeatures.orElse(Some(Cosmetics()))
}
else {
None
@@ -290,7 +297,7 @@ object AvatarConverter {
* @param builder the function used to transform to the decoded packet form
* @return a list of all items that were in the holsters in decoded packet form
*/
- private def MakeHolsters(obj : Player, builder : ((Int, Equipment) => InternalSlot)) : List[InternalSlot] = {
+ private def MakeHolsters(obj : Player, builder : (Int, Equipment) => InternalSlot) : List[InternalSlot] = {
recursiveMakeHolsters(obj.Holsters().iterator, builder)
}
@@ -338,7 +345,7 @@ object AvatarConverter {
* @param index which holster is currently being explored
* @return the `List` of inventory data created from the holsters
*/
- @tailrec private def recursiveMakeHolsters(iter : Iterator[EquipmentSlot], builder : ((Int, Equipment) => InternalSlot), list : List[InternalSlot] = Nil, index : Int = 0) : List[InternalSlot] = {
+ @tailrec private def recursiveMakeHolsters(iter : Iterator[EquipmentSlot], builder : (Int, Equipment) => InternalSlot, list : List[InternalSlot] = Nil, index : Int = 0) : List[InternalSlot] = {
if(!iter.hasNext) {
list
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/BoomerTriggerConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/BoomerTriggerConverter.scala
index 6f817afe..2d1ef391 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/BoomerTriggerConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/BoomerTriggerConverter.scala
@@ -2,16 +2,20 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.SimpleItem
-import net.psforever.packet.game.objectcreate.{BoomerTriggerData, DetailedBoomerTriggerData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedConstructionToolData, HandheldData}
+import net.psforever.types.PlanetSideEmpire
import scala.util.{Success, Try}
class BoomerTriggerConverter extends ObjectCreateConverter[SimpleItem]() {
- override def ConstructorData(obj : SimpleItem) : Try[BoomerTriggerData] = {
- Success(BoomerTriggerData())
+ override def ConstructorData(obj : SimpleItem) : Try[HandheldData] = {
+ Success(HandheldData(CommonFieldData()))
}
- override def DetailedConstructorData(obj : SimpleItem) : Try[DetailedBoomerTriggerData] = {
- Success(DetailedBoomerTriggerData())
+ override def DetailedConstructorData(obj : SimpleItem) : Try[DetailedConstructionToolData] = {
+ Success(DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ ))
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/CharacterSelectConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/CharacterSelectConverter.scala
index 9812e6a6..7a4414a5 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/CharacterSelectConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/CharacterSelectConverter.scala
@@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.definition.converter
-import net.psforever.objects.{EquipmentSlot, Player}
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.Player
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._
import net.psforever.types._
@@ -35,17 +36,21 @@ class CharacterSelectConverter extends AvatarConverter {
* @see `AvatarConverter.MakeAppearanceData`
* @return the resulting `CharacterAppearanceData`
*/
- private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
+ private def MakeAppearanceData(obj : Player) : Int=>CharacterAppearanceData = {
val aa : Int=>CharacterAppearanceA = CharacterAppearanceA(
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, CharacterVoice.Mute),
- black_ops = false,
- false,
- false,
- None,
- jammered = false,
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ v5 = None,
+ PlanetSideGUID(0)
+ ),
obj.ExoSuit,
- None,
- 0,
0,
0L,
0,
@@ -76,7 +81,7 @@ class CharacterSelectConverter extends AvatarConverter {
CharacterAppearanceData(aa, ab, RibbonBars())
}
- private def MakeDetailedCharacterData(obj : Player) : (Option[Int]=>DetailedCharacterData) = {
+ private def MakeDetailedCharacterData(obj : Player) : Option[Int]=>DetailedCharacterData = {
val bep : Long = obj.BEP
val maxOpt : Option[Long] = if(obj.ExoSuit == ExoSuitType.MAX) { Some(0L) } else { None }
val ba : DetailedCharacterA = DetailedCharacterA(
@@ -102,9 +107,9 @@ class CharacterSelectConverter extends AvatarConverter {
0L, 0L, 0L, 0L, 0L,
Some(DCDExtra2(0, 0)),
Nil, Nil, false,
- AvatarConverter.MakeCosmetics(bep)
+ AvatarConverter.MakeCosmetics(obj)
)
- (pad_length : Option[Int]) => DetailedCharacterData(ba, bb(bep, pad_length))(pad_length)
+ pad_length : Option[Int] => DetailedCharacterData(ba, bb(bep, pad_length))(pad_length)
}
/**
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/CommandDetonaterConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/CommandDetonaterConverter.scala
index 014d5bd8..0ce8e21c 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/CommandDetonaterConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/CommandDetonaterConverter.scala
@@ -2,16 +2,46 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.SimpleItem
-import net.psforever.packet.game.objectcreate.{CommandDetonaterData, DetailedCommandDetonaterData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedCommandDetonaterData, HandheldData}
+import net.psforever.types.PlanetSideEmpire
import scala.util.{Success, Try}
class CommandDetonaterConverter extends ObjectCreateConverter[SimpleItem]() {
- override def ConstructorData(obj : SimpleItem) : Try[CommandDetonaterData] = {
- Success(CommandDetonaterData())
+ override def ConstructorData(obj : SimpleItem) : Try[HandheldData] = {
+ Success(
+ HandheldData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
+ )
+ )
}
override def DetailedConstructorData(obj : SimpleItem) : Try[DetailedCommandDetonaterData] = {
- Success(DetailedCommandDetonaterData())
+ Success(
+ DetailedCommandDetonaterData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
+ )
+ )
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala
index e108fc22..bef8593a 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala
@@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.definition.converter
-import net.psforever.objects.{EquipmentSlot, Player}
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.Player
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._
import net.psforever.types._
@@ -30,17 +31,21 @@ class CorpseConverter extends AvatarConverter {
* @param obj the `Player` game object
* @return the resulting `CharacterAppearanceData`
*/
- private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
+ private def MakeAppearanceData(obj : Player) : Int=>CharacterAppearanceData = {
val aa : Int=>CharacterAppearanceA = CharacterAppearanceA(
BasicCharacterData(obj.Name, obj.Faction, CharacterGender.Male, 0, CharacterVoice.Mute),
- black_ops = false,
- altModel = true,
- false,
- None,
- jammered = false,
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ false,
+ None,
+ false,
+ None,
+ v5 = None,
+ PlanetSideGUID(0)
+ ),
obj.ExoSuit,
- None,
- 0,
0,
0L,
0,
@@ -71,7 +76,7 @@ class CorpseConverter extends AvatarConverter {
CharacterAppearanceData(aa, ab, RibbonBars())
}
- private def MakeDetailedCharacterData(obj : Player) : (Option[Int]=>DetailedCharacterData) = {
+ private def MakeDetailedCharacterData(obj : Player) : Option[Int]=>DetailedCharacterData = {
val maxOpt : Option[Long] = if(obj.ExoSuit == ExoSuitType.MAX) { Some(0L) } else { None }
val ba : DetailedCharacterA = DetailedCharacterA(
bep = 0L,
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/FieldTurretConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/FieldTurretConverter.scala
index 0139069d..9ced731e 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/FieldTurretConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/FieldTurretConverter.scala
@@ -11,22 +11,26 @@ import scala.util.{Failure, Success, Try}
class FieldTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
override def ConstructorData(obj : TurretDeployable) : Try[OneMannedFieldTurretData] = {
- val health = 255 * obj.Health / obj.MaxHealth //TODO not precise
+ val health = StatConverter.Health(obj.Health, obj.MaxHealth)
if(health > 3) {
Success(
OneMannedFieldTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 0,
- obj.Jammered,
- unk2 = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- }
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ )
),
health,
Some(InventoryData(FieldTurretConverter.MakeMountings(obj)))
@@ -36,18 +40,21 @@ class FieldTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
else {
Success(
OneMannedFieldTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- owner_guid = PlanetSideGUID(0)
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
),
- 0,
- None
+ 0
)
)
}
@@ -60,7 +67,7 @@ class FieldTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
object FieldTurretConverter {
private def MakeMountings(obj : WeaponTurret) : List[InventoryItemData.InventoryItem] = {
obj.Weapons.map({
- case((index, slot)) =>
+ case(index, slot) =>
val equip : Equipment = slot.Equipment.get
val equipDef = equip.Definition
InventoryItemData(equipDef.ObjectId, equip.GUID, index, equipDef.Packet.ConstructorData(equip).get)
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/ImplantTerminalInterfaceConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/ImplantTerminalInterfaceConverter.scala
deleted file mode 100644
index d27d167a..00000000
--- a/common/src/main/scala/net/psforever/objects/definition/converter/ImplantTerminalInterfaceConverter.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.definition.converter
-
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.packet.game.objectcreate.CommonTerminalData
-
-import scala.util.{Failure, Success, Try}
-
-class ImplantTerminalInterfaceConverter extends ObjectCreateConverter[Terminal]() {
- override def DetailedConstructorData(obj : Terminal) : Try[CommonTerminalData] =
- Failure(new Exception("ImplantTerminalInterfaceConverter should not be used to generate detailed CommonTerminalData"))
-
- override def ConstructorData(obj : Terminal) : Try[CommonTerminalData] =
- Success(CommonTerminalData(net.psforever.types.PlanetSideEmpire.VS)) //TODO shortcut
-}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/InternalTelepadDeployableConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/InternalTelepadDeployableConverter.scala
index a2b50cf9..780d5f89 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/InternalTelepadDeployableConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/InternalTelepadDeployableConverter.scala
@@ -3,12 +3,39 @@ package net.psforever.objects.definition.converter
import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.ce.TelepadLike
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
-import scala.util.{Success, Try}
+import scala.util.{Failure, Success, Try}
class InternalTelepadDeployableConverter extends ObjectCreateConverter[PlanetSideGameObject with TelepadLike]() {
- override def ConstructorData(obj : PlanetSideGameObject with TelepadLike) : Try[ContainedTelepadDeployableData] = {
- Success(ContainedTelepadDeployableData(101, obj.Router.get))
+ override def ConstructorData(obj : PlanetSideGameObject with TelepadLike) : Try[TelepadDeployableData] = {
+ obj.Router match {
+ case Some(PlanetSideGUID(0)) =>
+ Failure(new IllegalStateException("InternalTelepadDeployableConverter: knowledge of parent Router is null"))
+
+ case Some(router) =>
+ Success(
+ TelepadDeployableData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ Some(router.guid),
+ PlanetSideGUID(0)
+ ),
+ unk1 = 128,
+ unk2 = 0
+ )
+ )
+
+ case None =>
+ Failure(new IllegalStateException("InternalTelepadDeployableConverter: telepad needs to know id of its parent Router"))
+ }
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/KitConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/KitConverter.scala
index 1b0e137d..31176a73 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/KitConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/KitConverter.scala
@@ -2,13 +2,13 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.Kit
-import net.psforever.packet.game.objectcreate.{AmmoBoxData, DetailedAmmoBoxData}
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedAmmoBoxData}
import scala.util.{Success, Try}
class KitConverter extends ObjectCreateConverter[Kit]() {
- override def ConstructorData(obj : Kit) : Try[AmmoBoxData] = {
- Success(AmmoBoxData())
+ override def ConstructorData(obj : Kit) : Try[CommonFieldData] = {
+ Success(CommonFieldData()(false))
}
override def DetailedConstructorData(obj : Kit) : Try[DetailedAmmoBoxData] = {
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala
index 124a4c97..5a4a2083 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala
@@ -4,21 +4,34 @@ package net.psforever.objects.definition.converter
import net.psforever.objects.LockerContainer
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.inventory.GridInventory
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import scala.util.{Success, Try}
class LockerContainerConverter extends ObjectCreateConverter[LockerContainer]() {
override def ConstructorData(obj : LockerContainer) : Try[LockerContainerData] = {
- Success(LockerContainerData(InventoryData(MakeInventory(obj.Inventory))))
+ MakeInventory(obj.Inventory) match {
+ case Nil =>
+ Success(LockerContainerData(None))
+ case list =>
+ Success(LockerContainerData(InventoryData(list)))
+ }
}
override def DetailedConstructorData(obj : LockerContainer) : Try[DetailedLockerContainerData] = {
if(obj.Inventory.Size > 0) {
- Success(DetailedLockerContainerData(8, Some(InventoryData(MakeDetailedInventory(obj.Inventory)))))
+ Success(DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ Some(InventoryData(MakeDetailedInventory(obj.Inventory)))
+ ))
}
else {
- Success(DetailedLockerContainerData(8, None))
+ Success(DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ None
+ ))
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/REKConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/REKConverter.scala
index b35c789a..79446b2a 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/REKConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/REKConverter.scala
@@ -2,16 +2,45 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.SimpleItem
-import net.psforever.packet.game.objectcreate.{DetailedREKData, REKData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedREKData, REKData}
+import net.psforever.types.PlanetSideEmpire
import scala.util.{Success, Try}
class REKConverter extends ObjectCreateConverter[SimpleItem]() {
override def ConstructorData(obj : SimpleItem) : Try[REKData] = {
- Success(REKData(8,0))
+ Success(
+ REKData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL, //TODO faction affinity
+ false,
+ false,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0))
+ )
+ )
}
override def DetailedConstructorData(obj : SimpleItem) : Try[DetailedREKData] = {
- Success(DetailedREKData(8))
+ Success(
+ DetailedREKData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL, //TODO faction affinity
+ false,
+ false,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
+ )
+ )
}
-}
\ No newline at end of file
+}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/ShieldGeneratorConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/ShieldGeneratorConverter.scala
index 559d4152..75b77a9c 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/ShieldGeneratorConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/ShieldGeneratorConverter.scala
@@ -9,21 +9,26 @@ import scala.util.{Failure, Success, Try}
class ShieldGeneratorConverter extends ObjectCreateConverter[ShieldGeneratorDeployable]() {
override def ConstructorData(obj : ShieldGeneratorDeployable) : Try[AegisShieldGeneratorData] = {
- val health = 255 * obj.Health / obj.MaxHealth //TODO not precise
+ val health = StatConverter.Health(obj.Health, obj.MaxHealth)
if(health > 0) {
Success(
AegisShieldGeneratorData(
- CommonFieldData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk = 0,
- jammered = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- }
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ v1 = false,
+ v2 = None,
+ v3 = false,
+ None,
+ None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ )
),
health
)
@@ -32,14 +37,19 @@ class ShieldGeneratorConverter extends ObjectCreateConverter[ShieldGeneratorDepl
else {
Success(
AegisShieldGeneratorData(
- CommonFieldData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk = 0,
- jammered = false,
- player_guid = PlanetSideGUID(0)
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ v1 = false,
+ v2 = None,
+ v3 = false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
),
0
)
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/SmallDeployableConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/SmallDeployableConverter.scala
index bd327b21..7b10159b 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/SmallDeployableConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/SmallDeployableConverter.scala
@@ -4,29 +4,33 @@ package net.psforever.objects.definition.converter
import net.psforever.objects.ce.Deployable
import net.psforever.objects.PlanetSideGameObject
import net.psforever.packet.game.PlanetSideGUID
-import net.psforever.packet.game.objectcreate.{PlacementData, SmallDeployableData}
+import net.psforever.packet.game.objectcreate._
import scala.util.{Failure, Success, Try}
class SmallDeployableConverter extends ObjectCreateConverter[PlanetSideGameObject with Deployable]() {
- override def ConstructorData(obj : PlanetSideGameObject with Deployable) : Try[SmallDeployableData] = {
+ override def ConstructorData(obj : PlanetSideGameObject with Deployable) : Try[CommonFieldDataWithPlacement] = {
Success(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- }
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ false,
+ None,
+ false,
+ Some(false),
+ None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ )
)
)
}
- override def DetailedConstructorData(obj : PlanetSideGameObject with Deployable) : Try[SmallDeployableData] =
- Failure(new Exception("converter should not be used to generate detailed SmallDeployableData"))
+ override def DetailedConstructorData(obj : PlanetSideGameObject with Deployable) : Try[CommonFieldDataWithPlacement] =
+ Failure(new Exception("converter should not be used to generate detailed small deployable data"))
}
\ No newline at end of file
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/SmallTurretConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/SmallTurretConverter.scala
index 25e74d52..ec01eccc 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/SmallTurretConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/SmallTurretConverter.scala
@@ -11,22 +11,26 @@ import scala.util.{Failure, Success, Try}
class SmallTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
override def ConstructorData(obj : TurretDeployable) : Try[SmallTurretData] = {
- val health = 255 * obj.Health / obj.MaxHealth //TODO not precise
+ val health = StatConverter.Health(obj.Health, obj.MaxHealth)
if(health > 0) {
Success(
SmallTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 0,
- obj.Jammered,
- unk2 = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- }
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ false,
+ None,
+ false,
+ Some(true),
+ None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ )
),
health,
Some(InventoryData(SmallTurretConverter.MakeMountings(obj)))
@@ -36,18 +40,21 @@ class SmallTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
else {
Success(
SmallTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- owner_guid = PlanetSideGUID(0)
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ false,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
),
- 0,
- None
+ 0
)
)
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/SpawnTubeConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/SpawnTubeConverter.scala
index 56671f98..25957ae3 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/SpawnTubeConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/SpawnTubeConverter.scala
@@ -2,10 +2,10 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.serverobject.tube.SpawnTube
-import net.psforever.packet.game.objectcreate.CommonTerminalData
+import net.psforever.packet.game.objectcreate.CommonFieldData
import scala.util.{Success, Try}
class SpawnTubeConverter extends ObjectCreateConverter[SpawnTube]() {
- override def ConstructorData(obj : SpawnTube) : Try[CommonTerminalData] = { Success(CommonTerminalData(obj.Faction)) }
+ override def ConstructorData(obj : SpawnTube) : Try[CommonFieldData] = { Success(CommonFieldData(obj.Faction)(false)) }
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/StatConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/StatConverter.scala
new file mode 100644
index 00000000..aa204fd6
--- /dev/null
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/StatConverter.scala
@@ -0,0 +1,20 @@
+package net.psforever.objects.definition.converter
+
+object StatConverter {
+ /**
+ * Takes a measure of a value against the maximum possible value and
+ * transforms it to a scaled number that can be written within a specific domain.
+ *
+ * The default (and absolutely common) situation writes a scaled number that can be represented by an unsigned `8u`.
+ * The maximum value is 255, or 2^8^ - 1.
+ * The minimum value is 0;
+ * but, due to how game models are represented at various health,
+ * the representable minimum value is allowed to plateau at 3.
+ * Any result less than 3 creates the same situation as if the result were 0.
+ */
+ def Health(health : Int, maxHealth : Int, min : Int = 3, max : Int = 255) : Int =
+ if(health < 1) 0
+ else if(health <= min || min >= max) min
+ else if(health >= maxHealth) max
+ else math.floor(max * health / maxHealth).toInt
+}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/TRAPConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/TRAPConverter.scala
index 3bcfa303..3c423a17 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/TRAPConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/TRAPConverter.scala
@@ -9,22 +9,26 @@ import scala.util.{Failure, Success, Try}
class TRAPConverter extends ObjectCreateConverter[TrapDeployable]() {
override def ConstructorData(obj : TrapDeployable) : Try[TRAPData] = {
- val health = 255 * obj.Health / obj.MaxHealth //TODO not precise
+ val health = StatConverter.Health(obj.Health, obj.MaxHealth)
if(health > 0) {
Success(
TRAPData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- }
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ Some(true),
+ None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ )
),
health
)
@@ -33,15 +37,19 @@ class TRAPConverter extends ObjectCreateConverter[TrapDeployable]() {
else {
Success(
TRAPData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- owner_guid = PlanetSideGUID(0)
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ true,
+ None,
+ false,
+ Some(true),
+ None,
+ PlanetSideGUID(0)
+ )
),
0
)
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/TelepadConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/TelepadConverter.scala
index 4a0b9094..07114a3b 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/TelepadConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/TelepadConverter.scala
@@ -2,24 +2,53 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.Telepad
-import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedConstructionToolData, HandheldData}
import scala.util.{Failure, Success, Try}
class TelepadConverter extends ObjectCreateConverter[Telepad]() {
- override def ConstructorData(obj : Telepad) : Try[TelepadData] = {
+ override def ConstructorData(obj : Telepad) : Try[HandheldData] = {
obj.Router match {
- case Some(_) =>
- Success(TelepadData (0, obj.Router))
+ case Some(router) =>
+ Success(
+ HandheldData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ Some(router.guid),
+ PlanetSideGUID(0)
+ )
+ )
+ )
case None =>
Failure(new IllegalStateException("TelepadConverter: telepad needs to know id of its router"))
}
}
- override def DetailedConstructorData(obj : Telepad) : Try[DetailedTelepadData] = {
+ override def DetailedConstructorData(obj : Telepad) : Try[DetailedConstructionToolData] = {
obj.Router match {
- case Some(_) =>
- Success(DetailedTelepadData (0, obj.Router))
+ case Some(router) =>
+ Success(
+ DetailedConstructionToolData(
+ CommonFieldData(
+ obj.Faction,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ Some(router.guid),
+ PlanetSideGUID(0)
+ )
+ )
+ )
case None =>
Failure(new IllegalStateException("TelepadConverter: telepad needs to know id of its router"))
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/TelepadDeployableConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/TelepadDeployableConverter.scala
index b424b070..9971940d 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/TelepadDeployableConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/TelepadDeployableConverter.scala
@@ -8,39 +8,59 @@ import net.psforever.packet.game.objectcreate._
import scala.util.{Failure, Success, Try}
class TelepadDeployableConverter extends ObjectCreateConverter[TelepadDeployable]() {
- override def ConstructorData(obj : TelepadDeployable) : Try[TelepadDeployableData] = {
- if(obj.Router.isEmpty || obj.Router.contains(PlanetSideGUID(0))) {
- Failure(new IllegalStateException("TelepadDeployableConverter: telepad deployable needs to know id of its router"))
- }
- else {
- if(obj.Health > 0) {
- Success(TelepadDeployableData(
- PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 2,
- unk2 = true,
- obj.Router.get,
- obj.Owner.getOrElse(PlanetSideGUID(0)),
- unk3 = 87,
- unk4 = 12
- ))
- }
- else {
- Success(TelepadDeployableData(
- PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk1 = 2,
- unk2 = true,
- obj.Router.get,
- owner_guid = PlanetSideGUID(0),
- unk3 = 0,
- unk4 = 6
- ))
- }
+ override def ConstructorData(obj : TelepadDeployable) : Try[DroppedItemData[TelepadDeployableData]] = {
+ obj.Router match {
+ case Some(PlanetSideGUID(0)) =>
+ Failure(new IllegalStateException("TelepadDeployableConverter: knowledge of associated Router is null"))
+
+ case Some(router) =>
+ if(obj.Health > 0) {
+ Success(
+ DroppedItemData(
+ PlacementData(obj.Position, obj.Orientation),
+ TelepadDeployableData(
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ Some(router.guid),
+ obj.Owner.getOrElse(PlanetSideGUID(0))
+ ),
+ unk1 = 87,
+ unk2 = 12
+ )
+ )
+ )
+ }
+ else {
+ Success(
+ DroppedItemData(
+ PlacementData(obj.Position, obj.Orientation),
+ TelepadDeployableData(
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ true,
+ None,
+ false,
+ None,
+ Some(router.guid),
+ PlanetSideGUID(0)
+ ),
+ unk1 = 0,
+ unk2 = 6
+ )
+ )
+ )
+ }
+
+ case None =>
+ Failure(new IllegalStateException("TelepadDeployableConverter: telepad needs to know id of its associated Router"))
}
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/TerminalConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/TerminalConverter.scala
index 440d8329..888c2e30 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/TerminalConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/TerminalConverter.scala
@@ -2,10 +2,10 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.packet.game.objectcreate.CommonTerminalData
+import net.psforever.packet.game.objectcreate.CommonFieldData
import scala.util.{Success, Try}
class TerminalConverter extends ObjectCreateConverter[Terminal]() {
- override def ConstructorData(obj : Terminal) : Try[CommonTerminalData] = { Success(CommonTerminalData(obj.Faction)) }
+ override def ConstructorData(obj : Terminal) : Try[CommonFieldData] = { Success(CommonFieldData(obj.Faction)(false)) }
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala
index 5718ff16..a7886d44 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala
@@ -2,29 +2,57 @@
package net.psforever.objects.definition.converter
import net.psforever.objects.Tool
-import net.psforever.packet.game.objectcreate.{DetailedWeaponData, InternalSlot, WeaponData}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{CommonFieldData, DetailedWeaponData, InternalSlot, WeaponData}
-import scala.collection.mutable.ListBuffer
import scala.util.{Success, Try}
class ToolConverter extends ObjectCreateConverter[Tool]() {
override def ConstructorData(obj : Tool) : Try[WeaponData] = {
- val maxSlot : Int = obj.MaxAmmoSlot
- val slots : ListBuffer[InternalSlot] = ListBuffer[InternalSlot]()
- (0 until maxSlot).foreach(index => {
+ val slots : List[InternalSlot] = (0 until obj.MaxAmmoSlot).map(index => {
val box = obj.AmmoSlots(index).Box
- slots += InternalSlot(box.Definition.ObjectId, box.GUID, index, box.Definition.Packet.ConstructorData(box).get)
- })
- Success(WeaponData(4,8, obj.FireModeIndex, slots.toList)(maxSlot))
+ InternalSlot(box.Definition.ObjectId, box.GUID, index, box.Definition.Packet.ConstructorData(box).get)
+ }).toList
+ Success(
+ WeaponData(
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ obj.FireModeIndex,
+ slots
+ )
+ )
}
override def DetailedConstructorData(obj : Tool) : Try[DetailedWeaponData] = {
- val maxSlot : Int = obj.MaxAmmoSlot
- val slots : ListBuffer[InternalSlot] = ListBuffer[InternalSlot]()
- (0 until maxSlot).foreach(index => {
+ val slots : List[InternalSlot] = (0 until obj.MaxAmmoSlot).map(index => {
val box = obj.AmmoSlots(index).Box
- slots += InternalSlot(box.Definition.ObjectId, box.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get)
- })
- Success(DetailedWeaponData(4,8, obj.FireModeIndex, slots.toList)(maxSlot))
+ InternalSlot(box.Definition.ObjectId, box.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get)
+ }).toList
+ Success(
+ DetailedWeaponData(
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ obj.FireModeIndex,
+ slots
+ )
+ )
}
}
diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/VehicleConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/VehicleConverter.scala
index 0a11eba0..e0eb5461 100644
--- a/common/src/main/scala/net/psforever/objects/definition/converter/VehicleConverter.scala
+++ b/common/src/main/scala/net/psforever/objects/definition/converter/VehicleConverter.scala
@@ -4,7 +4,7 @@ package net.psforever.objects.definition.converter
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.Vehicle
import net.psforever.packet.game.PlanetSideGUID
-import net.psforever.packet.game.objectcreate.{InventoryData, InventoryItemData, ObjectClass, PlacementData, SpecificVehicleData, VehicleData, VehicleFormat}
+import net.psforever.packet.game.objectcreate._
import net.psforever.types.DriveState
import scala.util.{Failure, Success, Try}
@@ -14,21 +14,25 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
Failure(new Exception("VehicleConverter should not be used to generate detailed VehicleData (nothing should)"))
override def ConstructorData(obj : Vehicle) : Try[VehicleData] = {
- val health = 255 * obj.Health / obj.MaxHealth //TODO not precise
+ val health = StatConverter.Health(obj.Health, obj.MaxHealth)
if(health > 0) { //active
Success(
VehicleData(
PlacementData(obj.Position, obj.Orientation, obj.Velocity),
- obj.Faction,
- bops = false,
- destroyed = false,
- unk1 = 0,
- obj.Jammered,
- unk2 = false,
- obj.Owner match {
- case Some(owner) => owner
- case None => PlanetSideGUID(0)
- },
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = false,
+ v1 = false,
+ v2 = None,
+ v3 = false,
+ v4 = Some(false),
+ v5 = None,
+ obj.Owner match {
+ case Some(owner) => owner
+ case None => PlanetSideGUID(0)
+ }
+ ),
unk3 = false,
health,
unk4 = false,
@@ -46,13 +50,17 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
Success(
VehicleData(
PlacementData(obj.Position, obj.Orientation),
- obj.Faction,
- bops = false,
- destroyed = true,
- unk1 = 0,
- jammered = false,
- unk2 = false,
- owner_guid = PlanetSideGUID(0),
+ CommonFieldData(
+ obj.Faction,
+ bops = false,
+ alternate = true,
+ v1 = false,
+ v2 = None,
+ v3 = false,
+ v4 = Some(false),
+ v5 = None,
+ guid = PlanetSideGUID(0)
+ ),
unk3 = false,
health = 0,
unk4 = false,
@@ -80,7 +88,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
private def MakeMountings(obj : Vehicle) : List[InventoryItemData.InventoryItem] = {
obj.Weapons.map({
- case((index, slot)) =>
+ case(index, slot) =>
val equip : Equipment = slot.Equipment.get
val equipDef = equip.Definition
InventoryItemData(equipDef.ObjectId, equip.GUID, index, equipDef.Packet.ConstructorData(equip).get)
diff --git a/common/src/main/scala/net/psforever/objects/equipment/CItem.scala b/common/src/main/scala/net/psforever/objects/equipment/CItem.scala
index 0989207a..eda138d3 100644
--- a/common/src/main/scala/net/psforever/objects/equipment/CItem.scala
+++ b/common/src/main/scala/net/psforever/objects/equipment/CItem.scala
@@ -1,6 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.equipment
+/**
+ * An `Enumeration` of all the construction tool objects in the game, paired with their object id as the `Value`.
+ */
object CItem extends Enumeration {
final val ace = Value(32)
final val advanced_ace = Value(39) //fdu
diff --git a/common/src/main/scala/net/psforever/objects/equipment/Equipment.scala b/common/src/main/scala/net/psforever/objects/equipment/Equipment.scala
index 54e67a70..13ccaa80 100644
--- a/common/src/main/scala/net/psforever/objects/equipment/Equipment.scala
+++ b/common/src/main/scala/net/psforever/objects/equipment/Equipment.scala
@@ -4,6 +4,8 @@ package net.psforever.objects.equipment
import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.definition.EquipmentDefinition
import net.psforever.objects.inventory.InventoryTile
+import net.psforever.objects.serverobject.affinity.FactionAffinity
+import net.psforever.types.PlanetSideEmpire
/**
* `Equipment` is anything that can be:
@@ -12,7 +14,17 @@ import net.psforever.objects.inventory.InventoryTile
* and, special carried (like a lattice logic unit);
* and, dropped on the ground in the game world and render where it was deposited.
*/
-abstract class Equipment extends PlanetSideGameObject {
+abstract class Equipment extends PlanetSideGameObject
+ with FactionAffinity {
+ private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
+
+ def Faction : PlanetSideEmpire.Value = faction
+
+ override def Faction_=(fact : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
+ faction = fact
+ Faction
+ }
+
def Size : EquipmentSize.Value = Definition.Size
def Tile : InventoryTile = Definition.Tile
diff --git a/common/src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala b/common/src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala
index 564dca62..fca75943 100644
--- a/common/src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala
+++ b/common/src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala
@@ -1,6 +1,10 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.equipment
+/**
+ * An `Enumeration` of common equipment sizes in the game.
+ * Check the comments for originating use.
+ */
object EquipmentSize extends Enumeration {
val
Blocked,
diff --git a/common/src/main/scala/net/psforever/objects/EquipmentSlot.scala b/common/src/main/scala/net/psforever/objects/equipment/EquipmentSlot.scala
similarity index 94%
rename from common/src/main/scala/net/psforever/objects/EquipmentSlot.scala
rename to common/src/main/scala/net/psforever/objects/equipment/EquipmentSlot.scala
index dd2d4ab6..57b678f3 100644
--- a/common/src/main/scala/net/psforever/objects/EquipmentSlot.scala
+++ b/common/src/main/scala/net/psforever/objects/equipment/EquipmentSlot.scala
@@ -1,7 +1,5 @@
// Copyright (c) 2017 PSForever
-package net.psforever.objects
-
-import net.psforever.objects.equipment.{Equipment, EquipmentSize}
+package net.psforever.objects.equipment
/**
* A size-checked unit of storage (or mounting) for `Equipment`.
diff --git a/common/src/main/scala/net/psforever/objects/equipment/SItem.scala b/common/src/main/scala/net/psforever/objects/equipment/SItem.scala
index 8aea0f85..d8890e7b 100644
--- a/common/src/main/scala/net/psforever/objects/equipment/SItem.scala
+++ b/common/src/main/scala/net/psforever/objects/equipment/SItem.scala
@@ -1,6 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.equipment
+/**
+ * An `Enumeration` of some activation-type `Equipment` in the game, paired with their object id as the `Value`.
+ */
object SItem extends Enumeration {
final val boomer_trigger = Value(149)
final val command_detonater = Value(213) //cud
diff --git a/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala b/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala
index dd104f5a..3443ad96 100644
--- a/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala
+++ b/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala
@@ -3,7 +3,7 @@ package net.psforever.objects.guid
import akka.actor.ActorRef
import net.psforever.objects.entity.IdentifiableEntity
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.objects._
import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.turret.WeaponTurret
diff --git a/common/src/main/scala/net/psforever/objects/inventory/Container.scala b/common/src/main/scala/net/psforever/objects/inventory/Container.scala
index 72450076..a75261eb 100644
--- a/common/src/main/scala/net/psforever/objects/inventory/Container.scala
+++ b/common/src/main/scala/net/psforever/objects/inventory/Container.scala
@@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.inventory
-import net.psforever.objects.equipment.Equipment
-import net.psforever.objects.{EquipmentSlot, OffhandEquipmentSlot}
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
+import net.psforever.objects.OffhandEquipmentSlot
import net.psforever.packet.game.PlanetSideGUID
import scala.util.Try
diff --git a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala
index a0694493..c7a5a28a 100644
--- a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala
+++ b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala
@@ -3,8 +3,7 @@ package net.psforever.objects.inventory
import java.util.concurrent.atomic.AtomicInteger
-import net.psforever.objects.equipment.Equipment
-import net.psforever.objects.EquipmentSlot
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.packet.game.PlanetSideGUID
import scala.annotation.tailrec
diff --git a/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala b/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala
index 5bcf4125..12e0cf41 100644
--- a/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala
+++ b/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala
@@ -3,7 +3,7 @@ package net.psforever.objects.loadouts
import net.psforever.objects._
import net.psforever.objects.definition._
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.objects.inventory.InventoryItem
import scala.annotation.tailrec
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala
deleted file mode 100644
index f10f646d..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-class AirVehicleTerminalDefinition extends VehicleTerminalDefinition(43) {
- vehicles = flight1Vehicles
- Name = "air_vehicle_terminal"
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala
deleted file mode 100644
index 61b651b2..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-class BFRTerminalDefinition extends VehicleTerminalDefinition(143) {
- vehicles = bfrVehicles
- Name = "bfr_terminal"
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala
index 1143b2d8..fe288791 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala
@@ -1,22 +1,14 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
-import net.psforever.objects.Player
-import net.psforever.packet.game.ItemTransactionMessage
import net.psforever.types.CertificationType
-/**
- * The definition for any `Terminal` that is of a type "cert_terminal" (certification terminal).
- * `Learn` and `Sell` `CertificationType` entries, gaining access to different `Equipment` and `Vehicles`.
- */
-class CertTerminalDefinition extends TerminalDefinition(171) {
- Name = "cert_terminal"
-
+object CertTerminalDefinition {
/**
* The certifications available.
* All entries are listed on page (tab) number 0.
*/
- private val certificationList : Map[String, CertificationType.Value] = Map(
+ val certs : Map[String, CertificationType.Value] = Map(
"medium_assault" -> CertificationType.MediumAssault,
"reinforced_armor" -> CertificationType.ReinforcedExoSuit,
"quad_all" -> CertificationType.ATV,
@@ -59,34 +51,4 @@ class CertTerminalDefinition extends TerminalDefinition(171) {
"advanced_medical" -> CertificationType.AdvancedMedical
//TODO bfr certification entries
)
-
- /**
- * Process a `TransactionType.Learn` action by the user.
- * @param player the player
- * @param msg the original packet carrying the request
- * @return an actionable message that explains how to process the request
- */
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { //Learn
- certificationList.get(msg.item_name) match {
- case Some(cert) =>
- Terminal.LearnCertification(cert)
- case None =>
- Terminal.NoDeal()
- }
- }
-
- /**
- * Process a `TransactionType.Sell` action by the user.
- * @param player the player
- * @param msg the original packet carrying the request
- * @return an actionable message that explains how to process the request
- */
- override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- certificationList.get(msg.item_name) match {
- case Some(cert) =>
- Terminal.SellCertification(cert)
- case None =>
- Terminal.NoDeal()
- }
- }
}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala
deleted file mode 100644
index 02b56027..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-class DropshipVehicleTerminalDefinition extends VehicleTerminalDefinition(263) {
- vehicles = flight1Vehicles ++ flight2Vehicles
- Name = "dropship_vehicle_terminal"
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/EquipmentTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/EquipmentTerminalDefinition.scala
index 91500a70..2f1d56c7 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/EquipmentTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/EquipmentTerminalDefinition.scala
@@ -10,24 +10,6 @@ import net.psforever.types.ExoSuitType
import scala.annotation.switch
-abstract class EquipmentTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
- Name = "equipment_terminal"
-
- /**
- * Process a `TransactionType.Sell` action by the user.
- * There is no specific tab associated with this action.
- * It is a common button on the terminal interface window.
- * Additionally, the equipment to be sold ia almost always in the player's `FreeHand` slot.
- * Selling `Equipment` is always permitted.
- * @param player the player
- * @param msg the original packet carrying the request
- * @return an actionable message that explains how to process the request
- */
- override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- Terminal.SellEquipment()
- }
-}
-
object EquipmentTerminalDefinition {
private[this] val log = org.log4s.getLogger("TerminalDefinition")
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala
deleted file mode 100644
index aa61fba1..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-class GroundVehicleTerminalDefinition extends VehicleTerminalDefinition(386) {
- vehicles = groundVehicles
- Name = "ground_vehicle_terminal"
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalDefinition.scala
new file mode 100644
index 00000000..3efe5dd6
--- /dev/null
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalDefinition.scala
@@ -0,0 +1,27 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.objects.serverobject.terminals
+
+import net.psforever.objects.GlobalDefinitions
+import net.psforever.objects.definition.ImplantDefinition
+
+/**
+ * Data for the `Definition` for any `Terminal` that is of a type "implant_terminal_interface."
+ * Implant terminals are composed of two components.
+ * This `Definition` constructs the invisible interface component (interacted with as a game window).
+ * Unlike other `Terminal` objects in the game, this one must be constructed on the client and
+ * attached as a child of the visible implant terminal component - the "implant_terminal_mech."
+ */
+object ImplantTerminalDefinition {
+ val implants : Map[String, ImplantDefinition] = Map (
+ "advanced_regen" -> GlobalDefinitions.advanced_regen,
+ "targeting" -> GlobalDefinitions.targeting,
+ "audio_amplifier" -> GlobalDefinitions.audio_amplifier,
+ "darklight_vision" -> GlobalDefinitions.darklight_vision,
+ "melee_booster" -> GlobalDefinitions.melee_booster,
+ "personal_shield" -> GlobalDefinitions.personal_shield,
+ "range_magnifier" -> GlobalDefinitions.range_magnifier,
+ "second_wind" -> GlobalDefinitions.second_wind,
+ "silent_run" -> GlobalDefinitions.silent_run,
+ "surge" -> GlobalDefinitions.surge
+ )
+}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalInterfaceDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalInterfaceDefinition.scala
deleted file mode 100644
index 51c62e4e..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ImplantTerminalInterfaceDefinition.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-import net.psforever.objects.{GlobalDefinitions, Player}
-import net.psforever.objects.definition.ImplantDefinition
-import net.psforever.objects.definition.converter.ImplantTerminalInterfaceConverter
-import net.psforever.packet.game.ItemTransactionMessage
-import net.psforever.packet.game.objectcreate.ObjectClass
-
-/**
- * The `Definition` for any `Terminal` that is of a type "implant_terminal_interface."
- * Implant terminals are composed of two components.
- * This `Definition` constructs the invisible interface component (interacted with as a game window).
- * Unlike other `Terminal` objects in the game, this one must be constructed on the client and
- * attached as a child of the visible implant terminal component - the "implant_terminal_mech."
- */
-class ImplantTerminalInterfaceDefinition extends TerminalDefinition(ObjectClass.implant_terminal_interface) {
- Packet = new ImplantTerminalInterfaceConverter
- Name = "implant_terminal_interface"
-
- private val implants : Map[String, ImplantDefinition] = Map (
- "advanced_regen" -> GlobalDefinitions.advanced_regen,
- "targeting" -> GlobalDefinitions.targeting,
- "audio_amplifier" -> GlobalDefinitions.audio_amplifier,
- "darklight_vision" -> GlobalDefinitions.darklight_vision,
- "melee_booster" -> GlobalDefinitions.melee_booster,
- "personal_shield" -> GlobalDefinitions.personal_shield,
- "range_magnifier" -> GlobalDefinitions.range_magnifier,
- "second_wind" -> GlobalDefinitions.second_wind,
- "silent_run" -> GlobalDefinitions.silent_run,
- "surge" -> GlobalDefinitions.surge
- )
-
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- implants.get(msg.item_name) match {
- case Some(implant) =>
- Terminal.LearnImplant(implant)
- case None =>
- Terminal.NoDeal()
- }
- }
-
- override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- implants.get(msg.item_name) match {
- case Some(implant) =>
- Terminal.SellImplant(implant)
- case None =>
- Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/MatrixTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/MatrixTerminalDefinition.scala
index 292e30b2..a669de7f 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/MatrixTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/MatrixTerminalDefinition.scala
@@ -4,29 +4,19 @@ package net.psforever.objects.serverobject.terminals
import akka.actor.ActorContext
import net.psforever.objects.Player
import net.psforever.objects.serverobject.structures.Amenity
-import net.psforever.packet.game.ItemTransactionMessage
/**
* The definition for any `Terminal` that is of a type "matrix_terminal".
+ * Matrix terminal objects are used to create anchor points in the game environment
+ * in reference to a working set of spawn points attached to a `Building` object or `Vehicle` object
+ * depending on the spawn group.
+ * @see `SpawnTube`
+ * @see `Zone.CreateSpawnGroups`
+ * @see `Zone.SpawnGroups`
+ * @param objectId the object's identifier number
*/
-class MatrixTerminalDefinition(object_id : Int) extends TerminalDefinition(object_id) {
- Name = if(object_id == 517) {
- "matrix_terminala"
- }
- else if(object_id == 518) {
- "matrix_terminalb"
- }
- else if(object_id == 519) {
- "matrix_terminalc"
- }
- else if(object_id == 812) {
- "spawn_terminal"
- }
- else {
- throw new IllegalArgumentException("terminal must be object id 517-519 or 812")
- }
-
- override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
+class MatrixTerminalDefinition(objectId : Int) extends TerminalDefinition(objectId) {
+ def Request(player : Player, msg : Any) : Terminal.Exchange = Terminal.NoDeal()
}
object MatrixTerminalDefinition {
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/MedicalTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/MedicalTerminalDefinition.scala
index a1b26e03..29386a79 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/MedicalTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/MedicalTerminalDefinition.scala
@@ -1,6 +1,8 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
+import net.psforever.objects.Player
+
import scala.concurrent.duration.{Duration, FiniteDuration}
/**
@@ -8,7 +10,7 @@ import scala.concurrent.duration.{Duration, FiniteDuration}
* This includes the functionality of the formal medical terminals and some of the cavern crystals.
* Do not confuse the game's internal "medical_terminal" object category and the actual `medical_terminal` object (529).
*/
-class MedicalTerminalDefinition(objectId : Int) extends TerminalDefinition(objectId) with ProximityDefinition {
+class MedicalTerminalDefinition(objectId : Int) extends ProximityTerminalDefinition(objectId) {
private var interval : FiniteDuration = Duration(0, "seconds")
private var healAmount : Int = 0
private var armorAmount : Int = 0
@@ -37,4 +39,6 @@ class MedicalTerminalDefinition(objectId : Int) extends TerminalDefinition(objec
armorAmount = amount
ArmorAmount
}
+
+ override def Request(player : Player, msg : Any) : Terminal.Exchange = Terminal.NoDeal()
}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalABDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalABDefinition.scala
deleted file mode 100644
index c90aca31..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalABDefinition.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-import akka.actor.ActorContext
-import net.psforever.objects.Player
-import net.psforever.objects.loadouts.InfantryLoadout
-import net.psforever.objects.inventory.InventoryItem
-import net.psforever.objects.serverobject.structures.Amenity
-import net.psforever.packet.game.ItemTransactionMessage
-import net.psforever.objects.serverobject.terminals.EquipmentTerminalDefinition._
-import net.psforever.types.ExoSuitType
-
-/**
- * The definition for any `Terminal` that is of a type "ams_order_terminal".
- * As the name indicates, paired on the flanks of an advanced mobile spawn vehicle.
- *
- * `Buy` and `Sell` `Equipment` items and `AmmoBox` items.
- * Change `ExoSuitType` and retrieve `Loadout` entries.
- * Changing into mechanized assault exo-suits (MAXes) is not permitted.
- */
-class OrderTerminalABDefinition(object_id : Int) extends EquipmentTerminalDefinition(object_id) {
- if(object_id == 613) {
- Name = "order_terminala"
- }
- else if(object_id == 614) {
- Name = "order_terminalb"
- }
- else {
- throw new IllegalArgumentException("terminal must be either object id 613 or object id 614")
- }
-
- /**
- * The `Equipment` available from this `Terminal` on specific pages.
- */
- private val buyFunc : (Player, ItemTransactionMessage)=>Terminal.Exchange =
- EquipmentTerminalDefinition.Buy(
- infantryAmmunition ++ infantryWeapons,
- supportAmmunition ++ supportWeapons,
- suits
- )
-
- override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = buyFunc(player, msg)
-
- /**
- * Process a `TransactionType.Loadout` action by the user.
- * `Loadout` objects are blueprints composed of exo-suit specifications and simplified `Equipment`-to-slot mappings.
- * If a valid loadout is found, its data is transformed back into actual `Equipment` for return to the user.
- * Loadouts that would suit the player into a mechanized assault exo-suit are not permitted.
- * @param player the player
- * @param msg the original packet carrying the request
- * @return an actionable message that explains how to process the request
- */
- override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- if(msg.item_page == 4) { //Favorites tab
- player.LoadLoadout(msg.unk1) match {
- case Some(loadout : InfantryLoadout) =>
- if(loadout.exosuit != ExoSuitType.MAX) {
- val holsters = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
- val inventory = loadout.inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
- Terminal.InfantryLoadout(loadout.exosuit, loadout.subtype, holsters, inventory)
- }
- else {
- Terminal.NoDeal()
- }
- case Some(_) | None =>
- Terminal.NoDeal()
- }
- }
- else {
- Terminal.NoDeal()
- }
- }
-}
-
-object OrderTerminalABDefinition {
- /**
- * Assemble some logic for a provided object.
- * @param obj an `Amenity` object;
- * anticipating a `Terminal` object using this same definition
- * @param context hook to the local `Actor` system
- */
- def Setup(obj : Amenity, context : ActorContext) : Unit = {
- import akka.actor.{ActorRef, Props}
- if(obj.Actor == ActorRef.noSender) {
- obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
- }
- }
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala
index 9182d3b0..a53cb97e 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala
@@ -10,61 +10,39 @@ import net.psforever.objects.inventory.InventoryItem
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.packet.game.ItemTransactionMessage
import net.psforever.objects.serverobject.terminals.EquipmentTerminalDefinition._
-import net.psforever.types.{CertificationType, ExoSuitType}
+import net.psforever.types.{CertificationType, ExoSuitType, TransactionType}
import scala.collection.mutable
/**
- * The definition for any `Terminal` that is of a type "order_terminal".
- * This kind of "order_terminal" is applicable to facilities.
+ * The definition for any `Terminal` from which specifications can be altered.
+ * These specification alternations involve three classifications:
+ * the exchange of denominations of in-game hardware, i.e., `Equipment`,
+ * the modification of lists of personal statistics, e.g., `Certifications`,
+ * and saving and loading of preset configurations, i.e., `Loadouts`.
+ * This hardware is organized as "stock," occasionally supplemented.
+ * Terminals have tabs (visually) that are organized by different stock (internally)
+ * that determines the behavior available from that tab
+ * and what stock can be drawn or returned.
*
- * `Buy` and `Sell` `Equipment` items and `AmmoBox` items.
- * Change `ExoSuitType` and retrieve `Loadout` entries.
+ * Equipment terminals are the property of bases and vehicles ("amenities").
+ * To bases, the `Terminal` object is coupled loosely and may be allowed to diverge.
+ * To vehicles, the `Terminal` object is coupled directly to the faction affiliation of the vehicle.
+ * @see `Amenity`
+ * @see `Terminal`
+ * @see `Utility`
*/
-class OrderTerminalDefinition extends EquipmentTerminalDefinition(612) {
- Name = "order_terminal"
+class OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
+ /** An internal object organizing the different specification options found on a terminal's UI. */
+ private val tabs : mutable.HashMap[Int, OrderTerminalDefinition.Tab] =
+ new mutable.HashMap[Int, OrderTerminalDefinition.Tab]()
+ /** Disconnect the ability to return stock back to the terminal
+ * from the type of stock available from the terminal in general
+ * or the type of stock available from its denoted page.
+ * Will always return a message of type `SellEquipment`.*/
+ private var sellEquipmentDefault : Boolean = false
- /**
- * The `Equipment` available from this `Terminal` on specific pages.
- */
- private val buyFunc : (Player, ItemTransactionMessage)=>Terminal.Exchange = EquipmentTerminalDefinition.Buy(
- infantryAmmunition ++ infantryWeapons,
- supportAmmunition ++ supportWeapons,
- suits ++ maxSuits)
-
- override def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = buyFunc(player, msg)
-
- /**
- * Process a `TransactionType.Loadout` action by the user.
- * `Loadout` objects are blueprints composed of exo-suit specifications and simplified `Equipment`-to-slot mappings.
- * If a valid loadout is found, its data is transformed back into actual `Equipment` for return to the user.
- * @param player the player
- * @param msg the original packet carrying the request
- * @return an actionable message that explains how to process the request
- */
- override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- if(msg.item_page == 4) { //Favorites tab
- player.LoadLoadout(msg.unk1) match {
- case Some(loadout : InfantryLoadout) =>
- val holsters = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
- val inventory = loadout.inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
- Terminal.InfantryLoadout(loadout.exosuit, loadout.subtype, holsters, inventory)
- case Some(_) | None =>
- Terminal.NoDeal()
- }
- }
- else {
- Terminal.NoDeal()
- }
- }
-}
-
-class _OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
- private val pages : mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition] =
- new mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition]()
- private var sellEquipmentDefault : Boolean = true
-
- def Page : mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition] = pages
+ def Tab : mutable.HashMap[Int, OrderTerminalDefinition.Tab] = tabs
def SellEquipmentByDefault : Boolean = sellEquipmentDefault
@@ -73,8 +51,24 @@ class _OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
SellEquipmentByDefault
}
- override def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- pages.get(msg.item_page) match {
+ def Request(player : Player, msg : Any) : Terminal.Exchange = msg match {
+ case message : ItemTransactionMessage =>
+ message.transaction_type match {
+ case TransactionType.Buy | TransactionType.Learn =>
+ Buy(player, message)
+ case TransactionType.Loadout =>
+ Loadout(player, message)
+ case TransactionType.Sell =>
+ Sell(player, message)
+ case _ =>
+ Terminal.NoDeal()
+ }
+ case _ =>
+ Terminal.NoDeal()
+ }
+
+ private def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ tabs.get(msg.item_page) match {
case Some(page) =>
page.Buy(player, msg)
case _ =>
@@ -82,14 +76,14 @@ class _OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
}
}
- override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Buy(player, msg)
+ private def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Buy(player, msg)
- override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ private def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
if(sellEquipmentDefault) {
Terminal.SellEquipment()
}
else {
- pages.get(msg.item_page) match {
+ tabs.get(msg.item_page) match {
case Some(page) =>
page.Sell(player, msg)
case _ =>
@@ -99,14 +93,24 @@ class _OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
}
}
-object _OrderTerminalDefinition {
- abstract class PageDefinition(stock : Map[String, Any]) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange
+object OrderTerminalDefinition {
+ /**
+ * A basic tab outlining the specific type of stock available from this part of the terminal's interface.
+ * @see `ItemTransactionMessage`
+ */
+ sealed trait Tab {
+ def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
+ def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
- final case class ArmorPage(stock : Map[String, (ExoSuitType.Value, Int)]) extends PageDefinition(stock) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * The tab used to select an exo-suit to be worn by the player.
+ * @see `ExoSuitType`
+ * @param stock the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a tuple composed of an `ExoSuitType` value and a subtype value
+ */
+ final case class ArmorPage(stock : Map[String, (ExoSuitType.Value, Int)]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some((suit : ExoSuitType.Value, subtype : Int)) =>
Terminal.BuyExosuit(suit, subtype)
@@ -114,12 +118,42 @@ object _OrderTerminalDefinition {
Terminal.NoDeal()
}
}
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
- final case class CertificationPage(stock : Map[String, CertificationType.Value]) extends PageDefinition(stock) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * An expanded form of the tab used to select an exo-suit to be worn by the player that also provides some equipment.
+ * @see `ExoSuitType`
+ * @see `Equipment`
+ * @param stock the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a tuple composed of an `ExoSuitType` value and a subtype value
+ * @param items the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a curried function that produces an `Equipment` object
+ */
+ final case class ArmorWithAmmoPage(stock : Map[String, (ExoSuitType.Value, Int)], items : Map[String, ()=>Equipment]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ stock.get(msg.item_name) match {
+ case Some((suit : ExoSuitType.Value, subtype : Int)) =>
+ Terminal.BuyExosuit(suit, subtype)
+ case _ =>
+ items.get(msg.item_name) match {
+ case Some(item : (()=>Equipment)) =>
+ Terminal.BuyEquipment(item())
+ case _ =>
+ Terminal.NoDeal()
+ }
+ }
+ }
+ }
+
+ /**
+ * The tab used to select a certification to be utilized by the player.
+ * Only certifications may be returned to the interface defined by this page.
+ * @see `CertificationType`
+ * @param stock the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a `CertificationType` value
+ */
+ final case class CertificationPage(stock : Map[String, CertificationType.Value]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(cert : CertificationType.Value) =>
Terminal.LearnCertification(cert)
@@ -128,7 +162,7 @@ object _OrderTerminalDefinition {
}
}
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(cert : CertificationType.Value) =>
Terminal.SellCertification(cert)
@@ -138,8 +172,13 @@ object _OrderTerminalDefinition {
}
}
- final case class EquipmentPage(stock : Map[String, ()=>Equipment]) extends PageDefinition(stock) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * The tab used to produce an `Equipment` object to be used by the player.
+ * @param stock the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a curried function that produces an `Equipment` object
+ */
+ final case class EquipmentPage(stock : Map[String, ()=>Equipment]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(item : (()=>Equipment)) =>
Terminal.BuyEquipment(item())
@@ -147,12 +186,18 @@ object _OrderTerminalDefinition {
Terminal.NoDeal()
}
}
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.SellEquipment()
}
- final case class ImplantPage(stock : Map[String, ImplantDefinition]) extends PageDefinition(stock) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * The tab used to select an implant to be utilized by the player.
+ * A maximum of three implants can be obtained by any player at a time depending on the player's battle rank.
+ * Only implants may be returned to the interface defined by this page.
+ * @see `ImplantDefinition`
+ * @param stock the key is always a `String` value as defined from `ItemTransationMessage` data;
+ * the value is a `CertificationType` value
+ */
+ final case class ImplantPage(stock : Map[String, ImplantDefinition]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(implant : ImplantDefinition) =>
Terminal.LearnImplant(implant)
@@ -161,7 +206,7 @@ object _OrderTerminalDefinition {
}
}
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(implant : ImplantDefinition) =>
Terminal.SellImplant(implant)
@@ -171,8 +216,19 @@ object _OrderTerminalDefinition {
}
}
- final case class InfantryLoadoutPage() extends PageDefinition(Map.empty) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * The tab used to select which custom loadout the player is using.
+ * Player loadouts are defined by an exo-suit to be worn by the player
+ * and equipment in the holsters and the inventory.
+ * In this case, the reference to the player that is a parameter of the functions maintains information about the loadouts;
+ * no extra information specific to this page is necessary.
+ * @see `ExoSuitType`
+ * @see `Equipment`
+ * @see `InfantryLoadout`
+ * @see `Loadout`
+ */
+ final case class InfantryLoadoutPage() extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
player.LoadLoadout(msg.unk1) match {
case Some(loadout : InfantryLoadout) =>
val holsters = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
@@ -182,12 +238,20 @@ object _OrderTerminalDefinition {
Terminal.NoDeal()
}
}
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
- final case class VehicleLoadoutPage() extends PageDefinition(Map.empty) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ /**
+ * The tab used to select which custom loadout the player's vehicle is using.
+ * Vehicle loadouts are defined by a (superfluous) redefinition of the vehicle's mounted weapons
+ * and equipment in the trunk.
+ * In this case, the reference to the player that is a parameter of the functions maintains information about the loadouts;
+ * no extra information specific to this page is necessary.
+ * @see `Equipment`
+ * @see `Loadout`
+ * @see `VehicleLoadout`
+ */
+ final case class VehicleLoadoutPage() extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
player.LoadLoadout(msg.unk1 + 10) match {
case Some(loadout : VehicleLoadout) =>
val weapons = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
@@ -197,13 +261,21 @@ object _OrderTerminalDefinition {
Terminal.NoDeal()
}
}
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
+ /**
+ * The tab used to select a vehicle to be spawned for the player.
+ * Vehicle loadouts are defined by a superfluous redefinition of the vehicle's mounted weapons
+ * and equipment in the trunk
+ * for the purpose of establishing default contents.
+ * @see `Equipment`
+ * @see `Loadout`
+ * @see `Vehicle`
+ * @see `VehicleLoadout`
+ */
import net.psforever.objects.loadouts.{Loadout => Contents} //distinguish from Terminal.Loadout message
- final case class VehiclePage(stock : Map[String, ()=>Vehicle], trunk : Map[String, Contents]) extends PageDefinition(stock) {
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ final case class VehiclePage(stock : Map[String, ()=>Vehicle], trunk : Map[String, Contents]) extends Tab {
+ override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(vehicle) =>
val (weapons, inventory) = trunk.get(msg.item_name) match {
@@ -220,8 +292,6 @@ object _OrderTerminalDefinition {
Terminal.NoDeal()
}
}
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
/**
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala
index 5aa814d3..575d6e55 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala
@@ -1,20 +1,23 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
-import net.psforever.objects.{PlanetSideGameObject, Player}
-import net.psforever.packet.game.ItemTransactionMessage
+import net.psforever.objects.PlanetSideGameObject
+import net.psforever.objects.definition.ObjectDefinition
import scala.collection.mutable
/**
- * The definition for any `Terminal` that possesses a proximity-based effect.
+ * The definition mix-in for any game object that possesses a proximity-based effect.
* This includes the limited proximity-based functionality of the formal medical terminals
* and the actual proximity-based functionality of the cavern crystals.
- * Objects created by this definition being linked by their use of `ProximityTerminalUseMessage`.
+ * Objects created by this definition being linked by their communication
+ * between the server and client using `ProximityTerminalUseMessage` game packets.
*/
trait ProximityDefinition {
+ this : ObjectDefinition =>
+
private var useRadius : Float = 0f //TODO belongs on a wider range of object definitions
- private val targetValidation : mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean] = new mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean]()
+ private val targetValidation : mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean] = new mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean]()
def UseRadius : Float = useRadius
@@ -23,9 +26,9 @@ trait ProximityDefinition {
UseRadius
}
- def TargetValidation : mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean] = targetValidation
+ def TargetValidation : mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean] = targetValidation
- def Validations : Seq[(PlanetSideGameObject)=>Boolean] = {
+ def Validations : Seq[PlanetSideGameObject=>Boolean] = {
targetValidation.headOption match {
case Some(_) =>
targetValidation.values.toSeq
@@ -33,10 +36,8 @@ trait ProximityDefinition {
Seq(ProximityDefinition.Invalid)
}
}
-
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
object ProximityDefinition {
- protected val Invalid : (PlanetSideGameObject=>Boolean) = (_ : PlanetSideGameObject) => false
+ protected val Invalid : PlanetSideGameObject=>Boolean = (_ : PlanetSideGameObject) => false
}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala
index c34cbc11..0114c329 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala
@@ -1,6 +1,8 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
+import net.psforever.objects.Player
+import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.types.Vector3
import services.Service
@@ -13,14 +15,23 @@ import services.Service
* For example, the cavern crystals are considered owner-neutral elements that are not attached to a `Building` object.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
-class ProximityTerminal(tdef : TerminalDefinition with ProximityDefinition) extends Terminal(tdef) with ProximityUnit
+class ProximityTerminal(tdef : ProximityTerminalDefinition) extends Terminal(tdef) with ProximityUnit {
+ override def Request(player : Player, msg : Any) : Terminal.Exchange = {
+ msg match {
+ case message : CommonMessages.Use =>
+ Actor ! message
+ case _ =>
+ }
+ Terminal.NoDeal()
+ }
+}
object ProximityTerminal {
/**
* Overloaded constructor.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
- def apply(tdef : TerminalDefinition with ProximityDefinition) : ProximityTerminal = {
+ def apply(tdef : ProximityTerminalDefinition) : ProximityTerminal = {
new ProximityTerminal(tdef)
}
@@ -33,7 +44,7 @@ object ProximityTerminal {
* @param context a context to allow the object to properly set up `ActorSystem` functionality
* @return the `Terminal` object
*/
- def Constructor(tdef : TerminalDefinition with ProximityDefinition)(id : Int, context : ActorContext) : Terminal = {
+ def Constructor(tdef : ProximityTerminalDefinition)(id : Int, context : ActorContext) : Terminal = {
import akka.actor.Props
val obj = ProximityTerminal(tdef)
obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), s"${tdef.Name}_$id")
@@ -42,12 +53,13 @@ object ProximityTerminal {
/**
* Instantiate an configure a `Terminal` object, with position coordinates.
- * @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
- * @param id the unique id that will be assigned to this entity
+ * @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
+ * @param pos the location of the object
+ * @param id the unique id that will be assigned to this entity
* @param context a context to allow the object to properly set up `ActorSystem` functionality
* @return the `Terminal` object
*/
- def Constructor(tdef : TerminalDefinition with ProximityDefinition, pos : Vector3)(id : Int, context : ActorContext) : Terminal = {
+ def Constructor(tdef : ProximityTerminalDefinition, pos : Vector3)(id : Int, context : ActorContext) : Terminal = {
import akka.actor.Props
val obj = ProximityTerminal(tdef)
obj.Position = pos
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalDefinition.scala
new file mode 100644
index 00000000..ce0c5a15
--- /dev/null
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalDefinition.scala
@@ -0,0 +1,13 @@
+// Copyright (c) 2019 PSForever
+package net.psforever.objects.serverobject.terminals
+
+import net.psforever.objects.Player
+
+/**
+ *The definition for any `Terminal` that can be accessed for amenities and services,
+ * triggered when a certain distance from the unit itself (proximity-based).
+ * @param objectId the object's identifier number
+ */
+class ProximityTerminalDefinition(objectId : Int) extends TerminalDefinition(objectId) with ProximityDefinition {
+ def Request(player : Player, msg : Any) : Terminal.Exchange = Terminal.NoDeal()
+}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TeleportPadTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/TeleportPadTerminalDefinition.scala
deleted file mode 100644
index 4dd9872e..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TeleportPadTerminalDefinition.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-import akka.actor.ActorContext
-import net.psforever.objects.Player
-import net.psforever.objects.serverobject.structures.Amenity
-import net.psforever.packet.game.ItemTransactionMessage
-
-class TeleportPadTerminalDefinition extends EquipmentTerminalDefinition(853) {
- Name = "teleport_pad_terminal"
-
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- Terminal.BuyEquipment(EquipmentTerminalDefinition.routerTerminal("router_telepad")())
- }
-}
-
-object TeleportPadTerminalDefinition {
- /**
- * Assemble some logic for a provided object.
- * @param obj an `Amenity` object;
- * anticipating a `Terminal` object using this same definition
- * @param context hook to the local `Actor` system
- */
- def Setup(obj : Amenity, context : ActorContext) : Unit = {
- import akka.actor.{ActorRef, Props}
- if(obj.Actor == ActorRef.noSender) {
- obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
- }
- }
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala
index 387660a0..a75df70d 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala
@@ -6,10 +6,14 @@ import net.psforever.objects.definition.VehicleDefinition
import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.packet.game.{ItemTransactionMessage, TriggeredSound}
-import net.psforever.types.TransactionType
/**
- * A structure-owned server object that is a "terminal" that can be accessed for amenities and services.
+ * A server object that can be accessed for services and other amenities.
+ * Terminals are owned by both `Structure` objects and by `Vehicle` objects
+ * and generally conform to the faction affiliation of the owner.
+ * Some `Structure`-owned terminals may be compromised
+ * to extend functionality to other's not of faction affiliation for a short time
+ * while `Vehicle`-owned terminals may not.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
class Terminal(tdef : TerminalDefinition) extends Amenity with Hackable {
@@ -31,44 +35,23 @@ class Terminal(tdef : TerminalDefinition) extends Amenity with Hackable {
}
/**
- * Process some `TransactionType` action requested by the user.
+ * Process a message (a "request") dispatched by the user.
+ * To be accessible, the terminal must be owned by the same faction by the user or must be compromised.
+ * @see `FactionAffinity`
+ * @see `PlanetSideEmpire`
* @param player the player
* @param msg the original packet carrying the request
* @return an actionable message that explains what resulted from interacting with this `Terminal`
*/
- def Request(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
+ def Request(player : Player, msg : Any) : Terminal.Exchange = {
if(Faction == player.Faction || HackedBy.isDefined) {
- msg.transaction_type match {
- case TransactionType.Buy | TransactionType.Learn =>
- Buy(player, msg)
-
- case TransactionType.Sell =>
- Sell(player, msg)
-
- case TransactionType.Loadout =>
- Loadout(player, msg)
-
- case _ =>
- Terminal.NoDeal()
- }
+ tdef.Request(player, msg)
}
else {
Terminal.NoDeal()
}
}
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- tdef.Buy(player, msg)
- }
-
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- tdef.Sell(player, msg)
- }
-
- def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- tdef.Loadout(player, msg)
- }
-
def Definition : TerminalDefinition = tdef
}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala
index 562c6c91..5659e367 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala
@@ -3,10 +3,9 @@ package net.psforever.objects.serverobject.terminals
import net.psforever.objects.Player
import net.psforever.objects.definition.converter.TerminalConverter
-import net.psforever.packet.game.ItemTransactionMessage
/**
- * The basic definition for any `Terminal`.
+ * The basic definition for any `Terminal` object.
* @param objectId the object's identifier number
*/
abstract class TerminalDefinition(objectId : Int) extends net.psforever.objects.definition.ObjectDefinition(objectId) {
@@ -14,17 +13,12 @@ abstract class TerminalDefinition(objectId : Int) extends net.psforever.objects.
Packet = new TerminalConverter
/**
- * The unimplemented functionality for this `Terminal`'s `TransactionType.Buy` and `TransactionType.Learn` activity.
+ * The unimplemented functionality for the entry function of form of activity
+ * processed by this terminal and codified by the input message (a "request").
+ * @see `Terminal.Exchange`
+ * @param player the player who made the request
+ * @param msg the request message
+ * @return a message that resolves the transaction
*/
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange
-
- /**
- * The unimplemented functionality for this `Terminal`'s `TransactionType.Sell` activity.
- */
- def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
-
- /**
- * The unimplemented functionality for this `Terminal`'s `TransactionType.Loadout` activity.
- */
- def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
+ def Request(player : Player, msg : Any) : Terminal.Exchange
}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala
deleted file mode 100644
index bcbc35b3..00000000
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.objects.serverobject.terminals
-
-class VehicleTerminalCombinedDefinition extends VehicleTerminalDefinition(952) {
- vehicles = groundVehicles ++ flight1Vehicles
- Name = "vehicle_terminal_combined"
-}
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalDefinition.scala
index 553d5cc1..1684f665 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalDefinition.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalDefinition.scala
@@ -2,23 +2,17 @@
package net.psforever.objects.serverobject.terminals
import net.psforever.objects.definition.VehicleDefinition
-import net.psforever.objects.{Player, Vehicle}
+import net.psforever.objects.Vehicle
import net.psforever.objects.loadouts.VehicleLoadout
-import net.psforever.objects.inventory.InventoryItem
-import net.psforever.packet.game.ItemTransactionMessage
-
-abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
- protected var vehicles : Map[String, ()=>Vehicle] = Map()
- Name = "vehicle_terminal"
+object VehicleTerminalDefinition {
import net.psforever.objects.GlobalDefinitions._
- import VehicleTerminalDefinition.MakeVehicle
/**
* A `Map` of operations for producing a ground-based `Vehicle`.
* key - an identification string sent by the client
* value - a curried function that builds the object
*/
- protected val groundVehicles : Map[String, () => Vehicle] = Map(
+ val groundVehicles : Map[String, () => Vehicle] = Map(
"quadassault" -> MakeVehicle(quadassault),
"fury" -> MakeVehicle(fury),
"quadstealth" -> MakeVehicle(quadstealth),
@@ -50,7 +44,7 @@ abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition
* key - an identification string sent by the client
* value - a curried function that builds the object
*/
- protected val flight1Vehicles : Map[String, ()=>Vehicle] = Map(
+ val flight1Vehicles : Map[String, ()=>Vehicle] = Map(
"mosquito" -> MakeVehicle(mosquito),
"lightgunship" -> MakeVehicle(lightgunship),
"wasp" -> MakeVehicle(wasp),
@@ -64,7 +58,7 @@ abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition
* key - an identification string sent by the client
* value - a curried function that builds the object
*/
- protected val flight2Vehicles : Map[String, ()=>Vehicle] = Map(
+ val flight2Vehicles : Map[String, ()=>Vehicle] = Map(
"dropship" -> MakeVehicle(dropship),
"galaxy_gunship" -> MakeVehicle(galaxy_gunship),
"lodestar" -> MakeVehicle(lodestar)
@@ -75,7 +69,7 @@ abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition
* key - an identification string sent by the client
* value - a curried function that builds the object
*/
- protected val bfrVehicles : Map[String, ()=>Vehicle] = Map(
+ val bfrVehicles : Map[String, ()=>Vehicle] = Map(
// "colossus_gunner" -> (()=>Unit),
// "colossus_flight" -> (()=>Unit),
// "peregrine_gunner" -> (()=>Unit),
@@ -91,7 +85,7 @@ abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition
* key - an identification string sent by the client (for the vehicle)
* value - a curried function that builds the object
*/
- protected val trunk : Map[String, _Loadout] = {
+ val trunk : Map[String, _Loadout] = {
val ammo_12mm = ShorthandAmmoBox(bullet_12mm, bullet_12mm.Capacity)
val ammo_15mm = ShorthandAmmoBox(bullet_15mm, bullet_15mm.Capacity)
val ammo_25mm = ShorthandAmmoBox(bullet_25mm, bullet_25mm.Capacity)
@@ -483,26 +477,6 @@ abstract class VehicleTerminalDefinition(objId : Int) extends TerminalDefinition
)
}
- def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- vehicles.get(msg.item_name) match {
- case Some(vehicle) =>
- val (weapons, inventory) = trunk.get(msg.item_name) match {
- case Some(loadout : VehicleLoadout) =>
- (
- loadout.visible_slots.map(entry => { InventoryItem(EquipmentTerminalDefinition.BuildSimplifiedPattern(entry.item), entry.index) }),
- loadout.inventory.map(entry => { InventoryItem(EquipmentTerminalDefinition.BuildSimplifiedPattern(entry.item), entry.index) })
- )
- case _ =>
- (List.empty, List.empty)
- }
- Terminal.BuyVehicle(vehicle(), weapons, inventory)
- case None =>
- Terminal.NoDeal()
- }
- }
-}
-
-object VehicleTerminalDefinition {
/**
* Create a new `Vehicle` from provided `VehicleDefinition` objects.
* @param vdef the `VehicleDefinition` object
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurret.scala b/common/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurret.scala
index bdf777cb..18edfdd1 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurret.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurret.scala
@@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.turret
import net.psforever.objects.definition.{AmmoBoxDefinition, SeatDefinition, ToolDefinition}
import net.psforever.objects._
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.objects.inventory.{Container, GridInventory}
import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.serverobject.mount.Mountable
diff --git a/common/src/main/scala/net/psforever/objects/vehicles/MountedWeapons.scala b/common/src/main/scala/net/psforever/objects/vehicles/MountedWeapons.scala
index 3320496c..0d91e502 100644
--- a/common/src/main/scala/net/psforever/objects/vehicles/MountedWeapons.scala
+++ b/common/src/main/scala/net/psforever/objects/vehicles/MountedWeapons.scala
@@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.vehicles
-import net.psforever.objects.{EquipmentSlot, PlanetSideGameObject}
-import net.psforever.objects.equipment.Equipment
+import net.psforever.objects.PlanetSideGameObject
+import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.vehicles.{Seat => Chair}
diff --git a/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala b/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala
index 9b769c6b..97a8e745 100644
--- a/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala
+++ b/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala
@@ -45,11 +45,11 @@ object UtilityType extends Enumeration {
* Ostensibly, the purpose of the additional logic, when it is called,
* is to initialize a control `Actor` for the contained object.
* This `Actor` is expected by other logic.
+ * @see `Amenity.Owner`
* @see `Vehicle.LoadDefinition`
* @see `VehicleDefinition.Utilities`
* @param util the type of the `Amenity` object to be created
* @param vehicle the owner of this object
- * @see `Amenity.Owner`
*/
class Utility(util : UtilityType.Value, vehicle : Vehicle) {
private val obj : Amenity = Utility.BuildUtilityFunc(util)
@@ -154,9 +154,8 @@ object Utility {
* The `Terminal` `Utility` produced has proximity effects.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
- class ProximityTerminalUtility(tdef : TerminalDefinition) extends Terminal(tdef)
+ class ProximityTerminalUtility(tdef : ProximityTerminalDefinition) extends ProximityTerminal(tdef)
with UtilityWorldEntity
- with ProximityUnit
/**
* Override for a `Terminal` object so that it inherits the spatial characteristics of its `Owner`.
@@ -166,19 +165,26 @@ object Utility {
*/
class TeleportPadTerminalUtility(tdef : TerminalDefinition) extends TerminalUtility(tdef) {
/**
- * na
- * @param player na
- * @param msg na
- * @return na
+ * This kind of `Terminal` object only produces one object of importance - a Router's telepad unit.
+ * When this `Telepad` object is produced, it shlould be associated with the Router,
+ * that is, with the owner of the `Terminal` object.
+ * @param player the player who made the request
+ * @param msg the request message
+ * @return a message that resolves the transaction
*/
- override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
- val reply = super.Buy(player, msg)
- reply match {
- case Terminal.BuyEquipment(obj : Telepad) =>
- obj.Router = Owner.GUID
- case _ => ;
+ override def Request(player : Player, msg : Any) : Terminal.Exchange = {
+ msg match {
+ case message : ItemTransactionMessage =>
+ val reply = super.Request(player, message)
+ reply match {
+ case Terminal.BuyEquipment(obj : Telepad) =>
+ obj.Router = Owner.GUID
+ case _ => ;
+ }
+ reply
+ case _ =>
+ Terminal.NoDeal()
}
- reply
}
}
@@ -218,22 +224,20 @@ object Utility {
case UtilityType.ams_respawn_tube =>
SpawnTubeDefinition.Setup
case UtilityType.bfr_rearm_terminal =>
- _OrderTerminalDefinition.Setup
+ OrderTerminalDefinition.Setup
case UtilityType.lodestar_repair_terminal =>
ProximityTerminal.Setup
case UtilityType.matrix_terminalc =>
MatrixTerminalDefinition.Setup
case UtilityType.multivehicle_rearm_terminal =>
- _OrderTerminalDefinition.Setup
+ OrderTerminalDefinition.Setup
case UtilityType.order_terminala =>
- OrderTerminalABDefinition.Setup
+ OrderTerminalDefinition.Setup
case UtilityType.order_terminalb =>
- OrderTerminalABDefinition.Setup
+ OrderTerminalDefinition.Setup
case UtilityType.teleportpad_terminal =>
- TeleportPadTerminalDefinition.Setup
+ OrderTerminalDefinition.Setup
case UtilityType.internal_router_telepad_deployable =>
TelepadLike.Setup
}
-
- //private def defaultSetup(o1 : Amenity, o2 : ActorContext) : Unit = { }
}
diff --git a/common/src/main/scala/net/psforever/objects/vital/resistance/ResistanceCalculations.scala b/common/src/main/scala/net/psforever/objects/vital/resistance/ResistanceCalculations.scala
index 82b08dee..911d8f68 100644
--- a/common/src/main/scala/net/psforever/objects/vital/resistance/ResistanceCalculations.scala
+++ b/common/src/main/scala/net/psforever/objects/vital/resistance/ResistanceCalculations.scala
@@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.vital.resistance
-import net.psforever.objects.{ExoSuitDefinition, GlobalDefinitions}
+import net.psforever.objects.GlobalDefinitions
import net.psforever.objects.ballistics._
+import net.psforever.objects.definition.ExoSuitDefinition
import net.psforever.objects.vital.projectile.ProjectileCalculations
import net.psforever.types.ExoSuitType
diff --git a/common/src/main/scala/net/psforever/packet/PSPacket.scala b/common/src/main/scala/net/psforever/packet/PSPacket.scala
index bb516208..2ef4cbfd 100644
--- a/common/src/main/scala/net/psforever/packet/PSPacket.scala
+++ b/common/src/main/scala/net/psforever/packet/PSPacket.scala
@@ -236,10 +236,10 @@ object PacketHelpers {
* A `peek` that decodes like the normal but encodes nothing.
* Decoding `Codec[A]` from the input vector emits a value but reverts to the prior read position.
* Encoding `Codec[A]` to the input vector appends no new data to the input vector.
- * In effect, `peek` is a harmless meta-`Codec` that introduces no changes to the input vector.
+ * In effect, `peek` is a harmless meta-`Codec` that processes a value and introduces no changes to the input/output vector.
* @see `scodec.codecs.peek` or `codecs/package.scala:peek`
* @param target codec that decodes the value
- * @return codec that behaves the same as `target` but resets remainder to the input vector
+ * @return `Codec` that behaves the same as `target` but resets the contents of the vector as if `Codec` were never applied
*/
def peek[A](target: Codec[A]): Codec[A] = new Codec[A] {
def sizeBound = target.sizeBound
diff --git a/common/src/main/scala/net/psforever/packet/game/DeployRequestMessage.scala b/common/src/main/scala/net/psforever/packet/game/DeployRequestMessage.scala
index 0a38816a..7f40b7eb 100644
--- a/common/src/main/scala/net/psforever/packet/game/DeployRequestMessage.scala
+++ b/common/src/main/scala/net/psforever/packet/game/DeployRequestMessage.scala
@@ -41,10 +41,22 @@ final case class DeployRequestMessage(player_guid : PlanetSideGUID,
}
object DeployRequestMessage extends Marshallable[DeployRequestMessage] {
+ private val driveState3u = uint(3).xmap[DriveState.Value] (
+ n => DriveState(n),
+ n => {
+ if(n.id > 7) {
+ 0
+ }
+ else {
+ n.id
+ }
+ }
+ )
+
implicit val codec : Codec[DeployRequestMessage] = (
("player_guid" | PlanetSideGUID.codec) ::
("vehicle_guid" | PlanetSideGUID.codec) ::
- ("deploy_state" | DriveState.codec) ::
+ ("deploy_state" | driveState3u) ::
("unk2" | uint(5)) ::
("unk3" | bool) ::
("pos" | Vector3.codec_pos)
diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectCreateDetailedMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectCreateDetailedMessage.scala
index 7bbd21e8..0c2d9363 100644
--- a/common/src/main/scala/net/psforever/packet/game/ObjectCreateDetailedMessage.scala
+++ b/common/src/main/scala/net/psforever/packet/game/ObjectCreateDetailedMessage.scala
@@ -39,7 +39,7 @@ final case class ObjectCreateDetailedMessage(streamLength : Long,
objectClass : Int,
guid : PlanetSideGUID,
parentInfo : Option[ObjectCreateMessageParent],
- data : Option[ConstructorData])
+ data : ConstructorData)
extends PlanetSideGamePacket {
type Packet = ObjectCreateDetailedMessage
def opcode = GamePacketOpcode.ObjectCreateMessage
@@ -57,7 +57,7 @@ object ObjectCreateDetailedMessage extends Marshallable[ObjectCreateDetailedMess
*/
def apply(objectClass : Int, guid : PlanetSideGUID, parentInfo : ObjectCreateMessageParent, data : ConstructorData) : ObjectCreateDetailedMessage = {
val parentInfoOpt : Option[ObjectCreateMessageParent] = Some(parentInfo)
- ObjectCreateDetailedMessage(ObjectCreateBase.streamLen(parentInfoOpt, data), objectClass, guid, parentInfoOpt, Some(data))
+ ObjectCreateDetailedMessage(ObjectCreateBase.streamLen(parentInfoOpt, data), objectClass, guid, parentInfoOpt, data)
}
/**
@@ -68,7 +68,7 @@ object ObjectCreateDetailedMessage extends Marshallable[ObjectCreateDetailedMess
* @return an ObjectCreateMessage
*/
def apply(objectClass : Int, guid : PlanetSideGUID, data : ConstructorData) : ObjectCreateDetailedMessage = {
- ObjectCreateDetailedMessage(ObjectCreateBase.streamLen(None, data), objectClass, guid, None, Some(data))
+ ObjectCreateDetailedMessage(ObjectCreateBase.streamLen(None, data), objectClass, guid, None, data)
}
implicit val codec : Codec[ObjectCreateDetailedMessage] = ObjectCreateBase.baseCodec.exmap[ObjectCreateDetailedMessage] (
@@ -77,31 +77,36 @@ object ObjectCreateDetailedMessage extends Marshallable[ObjectCreateDetailedMess
Attempt.failure(Err("no data to decode"))
case len :: cls :: guid :: par :: data :: HNil =>
- val obj = ObjectCreateBase.decodeData(cls, data,
+ ObjectCreateBase.decodeData(cls, data,
if(par.isDefined) {
ObjectClass.selectDataDetailedCodec
}
else {
ObjectClass.selectDataDroppedDetailedCodec
}
- )
- Attempt.successful(ObjectCreateDetailedMessage(len, cls, guid, par, obj))
+ ) match {
+ case Attempt.Successful(obj) =>
+ Attempt.successful(ObjectCreateDetailedMessage(len, cls, guid, par, obj))
+ case Attempt.Failure(err) =>
+ Attempt.failure(err)
+ }
},
{
- case ObjectCreateDetailedMessage(_ , _ , _, _, None) =>
- Attempt.failure(Err("no object to encode"))
-
- case ObjectCreateDetailedMessage(_, cls, guid, par, Some(obj)) =>
+ case ObjectCreateDetailedMessage(_, cls, guid, par, obj) =>
val len = ObjectCreateBase.streamLen(par, obj) //even if a stream length has been assigned, it can not be trusted during encoding
- val bitvec = ObjectCreateBase.encodeData(cls, obj,
+ ObjectCreateBase.encodeData(cls, obj,
if(par.isDefined) {
ObjectClass.selectDataDetailedCodec
}
else {
ObjectClass.selectDataDroppedDetailedCodec
}
- )
- Attempt.successful(len :: cls :: guid :: par :: bitvec :: HNil)
+ ) match {
+ case Attempt.Successful(bvec) =>
+ Attempt.successful(len :: cls :: guid :: par :: bvec :: HNil)
+ case Attempt.Failure(err) =>
+ Attempt.failure(err)
+ }
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala
index bbe9108f..7fc98a58 100644
--- a/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala
+++ b/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala
@@ -2,7 +2,7 @@
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
-import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.objectcreate.{ObjectCreateBase, _}
import scodec.{Attempt, Codec, Err}
import scodec.bits.BitVector
import shapeless.{::, HNil}
@@ -50,7 +50,7 @@ final case class ObjectCreateMessage(streamLength : Long,
objectClass : Int,
guid : PlanetSideGUID,
parentInfo : Option[ObjectCreateMessageParent],
- data : Option[ConstructorData])
+ data : ConstructorData)
extends PlanetSideGamePacket {
type Packet = ObjectCreateMessage
def opcode = GamePacketOpcode.ObjectCreateMessage_Duplicate
@@ -68,7 +68,7 @@ object ObjectCreateMessage extends Marshallable[ObjectCreateMessage] {
*/
def apply(objectClass : Int, guid : PlanetSideGUID, parentInfo : ObjectCreateMessageParent, data : ConstructorData) : ObjectCreateMessage = {
val parentInfoOpt : Option[ObjectCreateMessageParent] = Some(parentInfo)
- ObjectCreateMessage(ObjectCreateBase.streamLen(parentInfoOpt, data), objectClass, guid, parentInfoOpt, Some(data))
+ ObjectCreateMessage(ObjectCreateBase.streamLen(parentInfoOpt, data), objectClass, guid, parentInfoOpt, data)
}
/**
@@ -79,7 +79,7 @@ object ObjectCreateMessage extends Marshallable[ObjectCreateMessage] {
* @return an `ObjectCreateMessage`
*/
def apply(objectClass : Int, guid : PlanetSideGUID, data : ConstructorData) : ObjectCreateMessage = {
- ObjectCreateMessage(ObjectCreateBase.streamLen(None, data), objectClass, guid, None, Some(data))
+ ObjectCreateMessage(ObjectCreateBase.streamLen(None, data), objectClass, guid, None, data)
}
implicit val codec : Codec[ObjectCreateMessage] = ObjectCreateBase.baseCodec.exmap[ObjectCreateMessage] (
@@ -88,31 +88,35 @@ object ObjectCreateMessage extends Marshallable[ObjectCreateMessage] {
Attempt.failure(Err("no data to decode"))
case len :: cls :: guid :: par :: data :: HNil =>
- val obj = ObjectCreateBase.decodeData(cls, data,
- if(par.isDefined) {
- ObjectClass.selectDataCodec
+ ObjectCreateBase.decodeData(cls, data, if(par.isDefined) {
+ ObjectClass.selectDataCodec
}
else {
ObjectClass.selectDataDroppedCodec
}
- )
- Attempt.successful(ObjectCreateMessage(len, cls, guid, par, obj))
+ ) match {
+ case Attempt.Successful(obj) =>
+ Attempt.successful(ObjectCreateMessage(len, cls, guid, par, obj))
+ case Attempt.Failure(err) =>
+ Attempt.failure(err)
+ }
},
{
- case ObjectCreateMessage(_ , _ , _, _, None) =>
- Attempt.failure(Err("no object to encode"))
-
- case ObjectCreateMessage(_, cls, guid, par, Some(obj)) =>
+ case ObjectCreateMessage(_, cls, guid, par, obj) =>
val len = ObjectCreateBase.streamLen(par, obj) //even if a stream length has been assigned, it can not be trusted during encoding
- val bitvec = ObjectCreateBase.encodeData(cls, obj,
+ ObjectCreateBase.encodeData(cls, obj,
if(par.isDefined) {
ObjectClass.selectDataCodec
}
else {
ObjectClass.selectDataDroppedCodec
}
- )
- Attempt.successful(len :: cls :: guid :: par :: bitvec :: HNil)
+ ) match {
+ case Attempt.Successful(bvec) =>
+ Attempt.successful(len :: cls :: guid :: par :: bvec :: HNil)
+ case Attempt.Failure(err) =>
+ Attempt.failure(err)
+ }
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ACEData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ACEData.scala
deleted file mode 100644
index ef6324e2..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ACEData.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of an adaptive construction engine (ACE).
- * This one-time-use item deploys a variety of utilities into the game environment.
- * Has an advanced version internally called an `advanced_ace` and commonly called a Field Deployment Unit (FDU).
- * @param unk1 na
- * @param unk2 na
- * @param unk3 na
- */
-final case class ACEData(unk1 : Int,
- unk2 : Int,
- unk3 : Int = 0
- ) extends ConstructorData {
- override def bitsize : Long = 34L
-}
-
-object ACEData extends Marshallable[ACEData] {
- implicit val codec : Codec[ACEData] = (
- ("unk1" | uint4L) ::
- ("unk2" | uint4L) ::
- uint(20) ::
- ("unk3" | uint4L) ::
- uint2L
- ).exmap[ACEData] (
- {
- case unk1 :: unk2 :: 0 :: unk3 :: 0 :: HNil =>
- Attempt.successful(ACEData(unk1, unk2, unk3))
- case _ :: _ :: _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid ace data format"))
- },
- {
- case ACEData(unk1, unk2, unk3) =>
- Attempt.successful(unk1 :: unk2 :: 0 :: unk3 :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/AegisShieldGeneratorData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/AegisShieldGeneratorData.scala
index 271d7ca7..b33becc5 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/AegisShieldGeneratorData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/AegisShieldGeneratorData.scala
@@ -11,7 +11,7 @@ import shapeless.{::, HNil}
* @param deploy data common to objects spawned by the (advanced) adaptive construction engine
* @param health the amount of health the object has, as a percentage of a filled bar
*/
-final case class AegisShieldGeneratorData(deploy : CommonFieldData,
+final case class AegisShieldGeneratorData(deploy : CommonFieldDataWithPlacement,
health : Int
) extends ConstructorData {
override def bitsize : Long = {
@@ -21,15 +21,16 @@ final case class AegisShieldGeneratorData(deploy : CommonFieldData,
object AegisShieldGeneratorData extends Marshallable[AegisShieldGeneratorData] {
implicit val codec : Codec[AegisShieldGeneratorData] = (
- ("deploy" | CommonFieldData.codec) ::
+ ("deploy" | CommonFieldDataWithPlacement.codec) ::
("health" | uint8L) ::
uint32 :: uint32 :: uint32 :: uint4L //100 bits
).exmap[AegisShieldGeneratorData] (
{
case deploy :: health :: 0 :: 0 :: 0 :: 0 :: HNil =>
Attempt.successful(AegisShieldGeneratorData(deploy, health))
- case _ =>
- Attempt.failure(Err("invalid aegis data format"))
+
+ case data =>
+ Attempt.failure(Err(s"invalid aegis data format - $data"))
},
{
case AegisShieldGeneratorData(deploy, health) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/AmmoBoxData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/AmmoBoxData.scala
index 90f1c281..df3c7dc4 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/AmmoBoxData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/AmmoBoxData.scala
@@ -1,53 +1,26 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game.objectcreate
-import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
/**
* A representation of ammunition that can be created using `ObjectCreateMessage` packet data.
* This data will help construct a "box" of that type of ammunition when standalone.
* It can also be constructed directly inside a weapon as its magazine.
*
- * This ammunition object ompletely ignores thr capacity field, normal to detailed ammunition objects.
- * Creating an object of this type directly and picking it up or observing it (in a weapon) reveals a single round.
- * @param unk na;
- * defaults to 0
+ * This ammunition object ompletely ignores the capacity field, normal to detailed ammunition objects.
+ * Creating an object of this type directly and picking it up or observing it (in a weapon) will reveals single round.
* @see `DetailedAmmoBoxData`
*/
-final case class AmmoBoxData(unk : Int = 0) extends ConstructorData {
- override def bitsize : Long = 24L
-}
-
-object AmmoBoxData extends Marshallable[AmmoBoxData] {
+object AmmoBoxData {
/**
* An abbreviated constructor for creating `AmmoBoxData` while masking use of `InternalSlot`.
* @param cls the code for the type of object being constructed
* @param guid the GUID this object will be assigned
* @param parentSlot a parent-defined slot identifier that explains where the child is to be attached to the parent
* @param ammo the ammunition object
- * @return an `InternalSlot` object that encapsulates `AmmoBoxData`
+ * @return an `InternalSlot` object that encapsulates `CommonFieldData`
*/
- def apply(cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : AmmoBoxData) : InternalSlot =
+ def apply(cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : CommonFieldData) : InternalSlot =
new InternalSlot(cls, guid, parentSlot, ammo)
-
- implicit val codec : Codec[AmmoBoxData] = (
- uint4L ::
- ("unk" | uint4L) :: // 8 - common - 4 - safe, 2 - stream misalignment, 1 - safe, 0 - common
- uint(16)
- ).exmap[AmmoBoxData] (
- {
- case 0xC :: unk :: 0 :: HNil =>
- Attempt.successful(AmmoBoxData(unk))
- case _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid ammunition data format"))
- },
- {
- case AmmoBoxData(unk) =>
- Attempt.successful(0xC :: unk :: 0 :: HNil)
- }
- )
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/BoomerTriggerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/BoomerTriggerData.scala
deleted file mode 100644
index f5e704b7..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/BoomerTriggerData.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of the detonator utility that is created when putting down a Boomer with an ACE.
- * @param unk na
- */
-final case class BoomerTriggerData(unk : Int = 0x8) extends ConstructorData {
- override def bitsize : Long = 34L
-}
-
-object BoomerTriggerData extends Marshallable[BoomerTriggerData] {
- implicit val codec : Codec[BoomerTriggerData] = (
- uint4L ::
- uint4L ::
- uint(26)
- ).exmap[BoomerTriggerData] (
- {
- case 0xC :: unk :: 0 :: HNil =>
- Attempt.successful(BoomerTriggerData(unk))
- case _ =>
- Attempt.failure(Err("invalid command detonater format"))
- },
- {
- case BoomerTriggerData(unk) =>
- Attempt.successful(0xC :: unk :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CaptureFlagData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CaptureFlagData.scala
index 44b32560..56e402d0 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CaptureFlagData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/CaptureFlagData.scala
@@ -50,8 +50,9 @@ object CaptureFlagData extends Marshallable[CaptureFlagData] {
{
case pos :: fac :: false :: 4 :: 0 :: unk1 :: 0 :: unk2 :: 0 :: unk3 :: unk4 :: 0 :: HNil =>
Attempt.Successful(CaptureFlagData(pos, fac, unk1, unk2, unk3, unk4))
- case _ =>
- Attempt.failure(Err("invalid capture flag data"))
+
+ case data =>
+ Attempt.failure(Err(s"invalid capture flag data format - $data"))
},
{
case CaptureFlagData(pos, fac, unk1, unk2, unk3, unk4) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterAppearanceData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterAppearanceData.scala
index 2bc98a36..c2b064d3 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterAppearanceData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterAppearanceData.scala
@@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game.objectcreate
+import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.{Marshallable, PacketHelpers}
import net.psforever.types._
import scodec.{Attempt, Codec, Err}
@@ -12,22 +13,20 @@ import shapeless.{::, HNil}
* @see `CharacterData`
* @see `DetailedCharacterData`
* @see `ExoSuitType`
- * @param app the player's cardinal appearance settings
- * @param black_ops whether or not this avatar is enrolled in Black OPs
- * @param jammered the player has been caught in an EMP blast recently;
- * creates a jammered sound effect that follows the player around and can be heard by others
- * @param exosuit the type of exo-suit the avatar will be depicted in;
- * for Black OPs, the agile exo-suit and the reinforced exo-suit are replaced with the Black OPs exo-suits
+ * @param app the player's cardinal appearance settings
+ * @param data common field data
+ * -bops - this vehicle belongs to the Black Ops, regardless of the faction field;
+ * activates the green camo and adjusts permissions
+ * -destroyed - flagged when using a model that is not the standard player in some stance
+ * -jammered - the player has been caught in an EMP blast recently;
+ * creates a jammered sound effect that follows the player around and can be heard by others
+ * -player_guid - does nothing?
+ * @param exosuit the type of exo-suit the avatar will be depicted in;
+ * for Black OPs, the agile exo-suit and the reinforced exo-suit are replaced with the Black OPs exo-suits
*/
final case class CharacterAppearanceA(app : BasicCharacterData,
- black_ops : Boolean,
- altModel : Boolean,
- unk1 : Boolean,
- unk2 : Option[CharacterAppearanceData.ExtraData],
- jammered : Boolean,
+ data : CommonFieldData,
exosuit : ExoSuitType.Value,
- unk3 : Option[Int],
- unk4 : Int,
unk5 : Int,
unk6 : Long,
unk7 : Int,
@@ -36,11 +35,9 @@ final case class CharacterAppearanceA(app : BasicCharacterData,
unkA : Int)
(name_padding : Int) extends StreamBitSize {
override def bitsize : Long = {
- //factor guard bool values into the base size, not its corresponding optional field
- val unk2Size : Long = unk2 match { case Some(n) => n.bitsize ; case None => 0L }
+ val dataSize : Long = data.bitsize
val nameStringSize : Long = StreamBitSize.stringBitSize(app.name, 16) + name_padding
- val unk3Size : Long = unk3 match { case Some(_) => 32L ; case None => 0L }
- 137L + unk2Size + nameStringSize + unk3Size
+ 114L + dataSize + nameStringSize
}
}
@@ -162,14 +159,23 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
val altModel : Boolean = backpack || on_zipline.isDefined
val a = CharacterAppearanceA(
app,
- black_ops,
- altModel,
- false,
- None,
- jammered,
+ CommonFieldData(
+ app.faction,
+ black_ops,
+ altModel,
+ false,
+ None,
+ false,
+ None,
+ if(jammered) {
+ Some(0)
+ }
+ else {
+ None
+ },
+ PlanetSideGUID(0)
+ ),
exosuit,
- None,
- 0,
0,
0,
0,
@@ -206,7 +212,7 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
def apply(a : Int=>CharacterAppearanceA, b : (Boolean,Int)=>CharacterAppearanceB, ribbons : RibbonBars)(name_padding : Int) : CharacterAppearanceData = {
val first = a(name_padding)
- CharacterAppearanceData(a(name_padding), b(first.altModel, name_padding), ribbons)(name_padding)
+ CharacterAppearanceData(a(name_padding), b(first.data.alternate, name_padding), ribbons)(name_padding)
}
/**
@@ -238,13 +244,18 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
* @return the length of the variable field that exists when using alternate models
*/
def altModelBit(app : CharacterAppearanceData) : Option[Int] = if(app.b.backpack || app.b.on_zipline.isDefined) {
- Some(1)
+ if(!app.a.data.alternate) {
+ throw new IllegalArgumentException("missing alternate model flag when should be set")
+ }
+ else {
+ Some(1)
+ }
}
else {
None
}
- def namePadding(inheritPad : Int, pad : Option[ExtraData]) : Int = {
+ def namePadding(inheritPad : Int, pad : Option[CommonFieldDataExtra]) : Int = {
pad match {
case Some(n) =>
val bitsize = n.bitsize.toInt % 8
@@ -282,45 +293,48 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
* @return na
*/
def a_codec(name_padding : Int) : Codec[CharacterAppearanceA] = (
- ("faction" | PlanetSideEmpire.codec) ::
- ("black_ops" | bool) ::
- (("alt_model" | bool) >>:~ { alt_model => //modifies stream format (to display alternate player models)
- ("unk1" | bool) :: //serves a different internal purpose depending on the state of alt_model
- (conditional(false, "unk2" | extra_codec) >>:~ { extra => //TODO not sure what causes this branch
- ("jammered" | bool) ::
- optional(bool, "unk3" | uint16L) ::
- ("unk4" | uint16L) ::
- ("name" | PacketHelpers.encodedWideStringAligned(namePadding(name_padding, extra))) ::
- ("exosuit" | ExoSuitType.codec) ::
- ("unk5" | uint2) :: //unknown
- ("sex" | CharacterGender.codec) ::
- ("head" | uint8L) ::
- ("voice" | CharacterVoice.codec) ::
- ("unk6" | uint32L) ::
- ("unk7" | uint16L) ::
- ("unk8" | uint16L) ::
- ("unk9" | uint16L) ::
- ("unkA" | uint16L) //usually either 0 or 65535
- })
- })
+ ("data" | CommonFieldData.codec) >>:~ { data =>
+ ("name" | PacketHelpers.encodedWideStringAligned(namePadding(name_padding, data.v2))) ::
+ ("exosuit" | ExoSuitType.codec) ::
+ ("unk5" | uint2) :: //unknown
+ ("sex" | CharacterGender.codec) ::
+ ("head" | uint8L) ::
+ ("voice" | CharacterVoice.codec) ::
+ ("unk6" | uint32L) ::
+ ("unk7" | uint16L) ::
+ ("unk8" | uint16L) ::
+ ("unk9" | uint16L) ::
+ ("unkA" | uint16L) //usually either 0 or 65535
+ }
).exmap[CharacterAppearanceA] (
{
- case faction :: bops :: alt :: u1 :: u2 :: jamd :: u3 :: u4 :: name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil =>
+ case data :: name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil =>
Attempt.successful(
- CharacterAppearanceA(BasicCharacterData(name, faction, sex, head, v1), bops, alt, u1, u2, jamd, suit, u3, u4, u5, u6, u7, u8, u9, uA)(name_padding)
+ CharacterAppearanceA(BasicCharacterData(name, data.faction, sex, head, v1), data, suit, u5, u6, u7, u8, u9, uA)(name_padding)
)
case _ =>
Attempt.Failure(Err("invalid character appearance data; can not encode"))
},
{
- case CharacterAppearanceA(BasicCharacterData(name, PlanetSideEmpire.NEUTRAL, _, _, _), _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
+ case CharacterAppearanceA(BasicCharacterData(name, PlanetSideEmpire.NEUTRAL, _, _, _), _, _, _, _, _, _, _, _) =>
Attempt.failure(Err(s"character $name's faction can not declare as neutral"))
- case CharacterAppearanceA(BasicCharacterData(name, faction, sex, head, v1), bops, alt, u1, u2, jamd, suit, u3, u4, u5, u6, u7, u8, u9, uA) =>
- Attempt.successful(
- faction :: bops :: alt :: u1 :: u2 :: jamd :: u3 :: u4 :: name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil
- )
+ case CharacterAppearanceA(BasicCharacterData(name, faction, sex, head, v1), data, suit, u5, u6, u7, u8, u9, uA) =>
+ if(faction != data.faction) {
+ Attempt.failure(Err(s"character $name's faction fields are mismatched, $faction != ${data.faction}"))
+ }
+ else if(data.faction == PlanetSideEmpire.NEUTRAL) {
+ Attempt.successful(
+ CommonFieldData(faction, data.bops, data.alternate, data.v1, data.v2, data.v3, None, data.v5, PlanetSideGUID(0)) ::
+ name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil
+ )
+ }
+ else {
+ Attempt.successful(
+ data :: name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil
+ )
+ }
case _ =>
Attempt.Failure(Err("invalid character appearance data; can not decode"))
@@ -385,7 +399,7 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
def codec(name_padding : Int) : Codec[CharacterAppearanceData] = (
("a" | a_codec(name_padding)) >>:~ { a =>
- ("b" | b_codec(a.altModel, name_padding)) ::
+ ("b" | b_codec(a.data.alternate, name_padding)) ::
("ribbons" | RibbonBars.codec)
}
).xmap[CharacterAppearanceData] (
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterData.scala
index a913b901..3a3fadb7 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/CharacterData.scala
@@ -27,7 +27,8 @@ object ImplantEffects extends Enumeration {
/**
* Values for the four different color designs that impact a player's uniform.
- * Exo-suits get minor graphical updates at the following battle rank levels: seven, fourteen, and twenty-five.
+ * Exo-suits get minor graphical updates at the following battle rank levels: seven (1), fourteen (2), and twenty-five (4).
+ * The values 3 and 5 also exist and are visually descriptive to the third upgrade.
*/
object UniformStyle extends Enumeration {
type Type = Value
@@ -35,9 +36,11 @@ object UniformStyle extends Enumeration {
val Normal = Value(0)
val FirstUpgrade = Value(1)
val SecondUpgrade = Value(2)
+ val SecondUpgradeEx = Value(3)
val ThirdUpgrade = Value(4)
+ val ThirdUpgradeEx = Value(5)
- implicit val codec = PacketHelpers.createEnumerationCodec(this, uintL(3))
+ implicit val codec = PacketHelpers.createEnumerationCodec(this, uint(3))
}
/**
@@ -115,7 +118,7 @@ object CharacterData extends Marshallable[CharacterData] {
uint(3) :: //uniform_upgrade is actually interpreted as a 6u field, but the lower 3u seems to be discarded
("command_rank" | uintL(3)) ::
listOfN(uint2, "implant_effects" | ImplantEffects.codec) ::
- conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
+ conditional(style.id > UniformStyle.SecondUpgrade.id,"cosmetics" | Cosmetics.codec)
})
).exmap[CharacterData] (
{
@@ -141,7 +144,7 @@ object CharacterData extends Marshallable[CharacterData] {
uint(3) :: //uniform_upgrade is actually interpreted as a 6u field, but the lower 3u seems to be discarded
("command_rank" | uintL(3)) ::
listOfN(uint2, "implant_effects" | ImplantEffects.codec) ::
- conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
+ conditional(style.id > UniformStyle.SecondUpgrade.id, "cosmetics" | Cosmetics.codec)
}
).exmap[CharacterData] (
{
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommandDetonaterData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommandDetonaterData.scala
deleted file mode 100644
index 0d5d46a2..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommandDetonaterData.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of the command uplink device.
- * I don't know much about the command uplink device so someone else has to provide this commentary.
- */
-final case class CommandDetonaterData(unk1 : Int = 0,
- unk2 : Int = 0) extends ConstructorData {
- override def bitsize : Long = 34L
-}
-
-object CommandDetonaterData extends Marshallable[CommandDetonaterData] {
- implicit val codec : Codec[CommandDetonaterData] = (
- ("unk1" | uint4L) ::
- ("unk2" | uint4L) ::
- uint(26)
- ).exmap[CommandDetonaterData] (
- {
- case unk1 :: unk2 :: 0 :: HNil =>
- Attempt.successful(CommandDetonaterData(unk1, unk2))
- case _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid command detonator data format"))
- },
- {
- case CommandDetonaterData(unk1, unk2) =>
- Attempt.successful(unk1 :: unk2 :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldData.scala
index 37ec4167..6c9ef68c 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldData.scala
@@ -8,96 +8,138 @@ import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
+final case class CommonFieldDataExtra(unk1 : Int, unk2 : Boolean) extends StreamBitSize {
+ override def bitsize : Long = 17L
+}
+
+object CommonFieldDataExtra {
+ implicit val codec : Codec[CommonFieldDataExtra] = (
+ ("unk1" | uint16L) ::
+ ("unk2" | bool)
+ ).as[CommonFieldDataExtra]
+}
+
/**
* Data that is common to a number of game object serializations.
- * @param pos where and how the object is oriented
- * @param faction association of the object with
- * @param unk na
- * @param player_guid the player who placed/leverages/[action]s this object
+ * @param faction faction affinity
+ * `NEUTRAL` when not required to be any specific value
+ * @param bops usually indicates black ops affiliation
+ * @param alternate usually indicates variance in model from default (e.g., vehicle is destroyed, player has released, etc.);
+ * when set on a tool, that tool will be rendered nonfunctional instead (though it can still be equipped)
+ * @param v1 na
+ * @param v2 na;
+ * optional data whose reading is triggered in unknown conditions;
+ * flag a weapon as "jammered"
+ * @param v3 na;
+ * for weapons, works like `alternate`
+ * @param v4 na;
+ * a field used by a second encoding format for this data
+ * @param v5 na;
+ * previously considered to flag as "jammered"
+ * @param guid usually indicates another active game object that placed/leverages/[action]s this object
*/
-final case class CommonFieldData(pos : PlacementData,
- faction : PlanetSideEmpire.Value,
+final case class CommonFieldData(faction : PlanetSideEmpire.Value,
bops : Boolean,
- destroyed : Boolean,
- unk : Int,
- jammered : Boolean,
- player_guid : PlanetSideGUID
- ) extends StreamBitSize {
- override def bitsize : Long = 23L + pos.bitsize
+ alternate : Boolean,
+ v1 : Boolean,
+ v2 : Option[CommonFieldDataExtra],
+ v3 : Boolean,
+ v4 : Option[Boolean],
+ v5 : Option[Int],
+ guid : PlanetSideGUID
+ ) extends ConstructorData {
+ override def bitsize : Long = {
+ val extraSize : Long = v2 match {
+ case Some(v) => v.bitsize
+ case None => 0L
+ }
+ val v4Size = v4 match {
+ case Some(_) => 1L
+ case None => 0L
+ }
+ val v5Size = v5 match {
+ case Some(_) => 16L
+ case None => 0L
+ }
+ 23L + extraSize + v4Size + v5Size
+ }
+
+ def apply(flag : Boolean) : CommonFieldData = CommonFieldData(faction, bops, alternate, v1, v2, v3, Some(flag), v5, guid)
}
object CommonFieldData extends Marshallable[CommonFieldData] {
- final val internalWeapon_bitsize : Long = 10
-
/**
- * Overloaded constructor that eliminates the need to list the fourth, optional, GUID field.
- * @param pos where and how the object is oriented
- * @param faction association of the object with
- * @param unk na
+ * Overloaded constructors.
* @return a `CommonFieldData` object
*/
- def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, unk : Int) : CommonFieldData =
- CommonFieldData(pos, faction, false, false, unk, false, PlanetSideGUID(0))
+ def apply() : CommonFieldData =
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0))
- def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, unk : Int, player_guid : PlanetSideGUID) : CommonFieldData =
- CommonFieldData(pos, faction, false, false, unk, false, player_guid)
+ def apply(faction : PlanetSideEmpire.Value) : CommonFieldData =
+ CommonFieldData(faction, false, false, false, None, false, None, None, PlanetSideGUID(0))
- def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int) : CommonFieldData =
- CommonFieldData(pos, faction, false, destroyed, unk, false, PlanetSideGUID(0))
+ def apply(faction : PlanetSideEmpire.Value, unk : Int) : CommonFieldData =
+ CommonFieldData(faction, false, false, unk>1, None, unk%1==1, None, None, PlanetSideGUID(0))
- def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int, player_guid : PlanetSideGUID) : CommonFieldData =
- CommonFieldData(pos, faction, false, destroyed, unk, false, player_guid)
+ def apply(faction : PlanetSideEmpire.Value, unk : Int, player_guid : PlanetSideGUID) : CommonFieldData =
+ CommonFieldData(faction, false, false, unk>1, None, unk%1==1, None, None, player_guid)
- /**
- * `Codec` for transforming reliable `WeaponData` from the internal structure of the turret when it is defined.
- * Works for both `SmallTurretData` and `OneMannedFieldTurretData`.
- */
- val internalWeaponCodec : Codec[InternalSlot] = (
- uint8L :: //number of internal weapons (should be 1)?
- uint2L ::
- InternalSlot.codec
- ).exmap[InternalSlot] (
+ def apply(faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int) : CommonFieldData =
+ CommonFieldData(faction, false, destroyed, unk>1, None, unk%1==1, None, None, PlanetSideGUID(0))
+
+ def apply(faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int, player_guid : PlanetSideGUID) : CommonFieldData =
+ CommonFieldData(faction, false, destroyed, unk>1, None, unk%1==1, None, None, player_guid)
+
+ def apply(faction : PlanetSideEmpire.Value, bops : Boolean, destroyed : Boolean, unk : Int, jammered : Boolean, player_guid : PlanetSideGUID) : CommonFieldData = {
+ val jammeredField = if(jammered) { Some(0) } else { None }
+ CommonFieldData(faction, bops, destroyed, unk>1, None, unk%1==1, None, jammeredField, player_guid)
+ }
+
+ def codec(extra : Boolean) : Codec[CommonFieldData] = (
+ ("faction" | PlanetSideEmpire.codec) ::
+ ("bops" | bool) ::
+ ("alternate" | bool) ::
+ ("v1" | bool) :: //the purpose of this bit changes depending on the previous bit
+ conditional(extra, "v2" | CommonFieldDataExtra.codec) ::
+ ("v3" | bool) ::
+ optional(bool, "v5" | uint16L) ::
+ ("guid" | PlanetSideGUID.codec)
+ ).xmap[CommonFieldData] (
{
- case 1 :: 0 :: InternalSlot(a1, b1, c1, WeaponData(a2, b2, c2, d)) :: HNil =>
- Attempt.successful(InternalSlot(a1, b1, c1, WeaponData(a2, b2, c2, d)))
-
- case 1 :: 0 :: InternalSlot(_, _, _, _) :: HNil =>
- Attempt.failure(Err(s"turret internals must contain weapon data"))
-
- case n :: 0 :: _ :: HNil =>
- Attempt.failure(Err(s"turret internals can not have $n weapons"))
-
- case _ =>
- Attempt.failure(Err("invalid turret internals data format"))
+ case faction :: bops :: alternate :: v1 :: v2 :: v3 :: v5 :: player_guid :: HNil =>
+ CommonFieldData(faction, bops, alternate, v1, v2, v3, None, v5, player_guid)
},
{
- case InternalSlot(a1, b1, c1, WeaponData(a2, b2, c2, d)) =>
- Attempt.successful(1 :: 0 :: InternalSlot(a1, b1, c1, WeaponData(a2, b2, c2, d)) :: HNil)
-
- case InternalSlot(_, _, _, _) =>
- Attempt.failure(Err(s"turret internals must contain weapon data"))
-
- case _ =>
- Attempt.failure(Err("invalid turret internals data format"))
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, _, v5, guid) =>
+ faction :: bops :: alternate :: v1 :: v2 :: v3 :: v5 :: guid :: HNil
}
)
- implicit val codec : Codec[CommonFieldData] = (
- ("pos" | PlacementData.codec) ::
- ("faction" | PlanetSideEmpire.codec) ::
+ implicit val codec : Codec[CommonFieldData] = codec(false)
+
+ def codec2(extra : Boolean) : Codec[CommonFieldData] = (
+ ("faction" | PlanetSideEmpire.codec) ::
("bops" | bool) ::
- ("destroyed" | bool) ::
- ("unk" | uint2L) :: //3 - na, 2 - common, 1 - na, 0 - common?
- ("jammered" | bool) ::
- ("player_guid" | PlanetSideGUID.codec)
+ ("alternate" | bool) ::
+ ("v1" | bool) :: //though the code path differs depending on the previous bit, this one gets read one way or another
+ conditional(extra, "v2" | CommonFieldDataExtra.codec) ::
+ ("v3" | bool) ::
+ optional(bool, "v5" | uint16L) ::
+ ("v4" | bool) ::
+ ("guid" | PlanetSideGUID.codec)
).exmap[CommonFieldData] (
{
- case pos :: fac :: bops :: wrecked :: unk :: jammered :: player :: HNil =>
- Attempt.successful(CommonFieldData(pos, fac, bops, wrecked, unk,jammered, player))
+ case faction :: bops :: alternate :: v1 :: v2 :: v3 :: v5 :: v4 :: guid :: HNil =>
+ Attempt.successful(CommonFieldData(faction, bops, alternate, v1, v2, v3, Some(v4), v5, guid))
},
{
- case CommonFieldData(pos, fac, bops, wrecked, unk, jammered, player) =>
- Attempt.successful(pos :: fac :: bops :: wrecked :: unk :: jammered :: player :: HNil)
+ case CommonFieldData(_, _, _, _, _, _, None, _, _) =>
+ Attempt.Failure(Err("invalid CommonFieldData - expected a field to be defined, but it was 'None'"))
+
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, Some(v4), v5, player_guid) =>
+ Attempt.successful(faction :: bops :: alternate :: v1 :: v2 :: v3 :: v5 :: v4 :: player_guid :: HNil)
}
)
+
+ val codec2 : Codec[CommonFieldData] = codec2(false)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldDataWithPlacement.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldDataWithPlacement.scala
new file mode 100644
index 00000000..790f7433
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonFieldDataWithPlacement.scala
@@ -0,0 +1,55 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.packet.game.objectcreate
+
+import net.psforever.packet.Marshallable
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
+import scodec.Codec
+import scodec.codecs._
+
+/**
+ * Data that is common to a number of game object serializations, plus position information
+ * @see `DroppedItemData`
+ * @param pos the location, orientation, and potential velocity of the object
+ * @param data the common fields
+ */
+final case class CommonFieldDataWithPlacement(pos : PlacementData,
+ data : CommonFieldData
+ ) extends ConstructorData {
+ override def bitsize : Long = pos.bitsize + data.bitsize
+}
+
+object CommonFieldDataWithPlacement extends Marshallable[CommonFieldDataWithPlacement] {
+ /**
+ * Overloaded constructors.
+ * @return a `CommonFieldDataWithPlacement` object
+ */
+ def apply(pos : PlacementData, faction : PlanetSideEmpire.Value) : CommonFieldDataWithPlacement =
+ CommonFieldDataWithPlacement(pos, CommonFieldData(faction))
+
+ def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, unk : Int) : CommonFieldDataWithPlacement =
+ CommonFieldDataWithPlacement(pos, CommonFieldData(faction, unk))
+
+ def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, unk : Int, player_guid : PlanetSideGUID) : CommonFieldDataWithPlacement =
+ CommonFieldDataWithPlacement(pos, CommonFieldData(faction, unk, player_guid))
+
+ def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int) : CommonFieldDataWithPlacement =
+ CommonFieldDataWithPlacement(pos, CommonFieldData(faction, destroyed, unk))
+
+ def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, destroyed : Boolean, unk : Int, player_guid : PlanetSideGUID) : CommonFieldDataWithPlacement =
+ CommonFieldDataWithPlacement(pos, CommonFieldData(faction, destroyed, unk, player_guid))
+
+ def codec(extra : Boolean) : Codec[CommonFieldDataWithPlacement] = (
+ ("pos" | PlacementData.codec) ::
+ CommonFieldData.codec(extra)
+ ).as[CommonFieldDataWithPlacement]
+
+ implicit val codec : Codec[CommonFieldDataWithPlacement] = codec(false)
+
+ def codec2(extra : Boolean) : Codec[CommonFieldDataWithPlacement] = (
+ ("pos" | PlacementData.codec) ::
+ CommonFieldData.codec2(extra)
+ ).as[CommonFieldDataWithPlacement]
+
+ implicit val codec2 : Codec[CommonFieldDataWithPlacement] = codec2(false)
+}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonTerminalData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonTerminalData.scala
deleted file mode 100644
index 39dc42a1..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/CommonTerminalData.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import net.psforever.types.PlanetSideEmpire
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of an object that can be interacted with when using a variety of terminals.
- * This object is generally invisible.
- * @param faction the faction that can access the terminal
- * @param unk na
- */
-final case class CommonTerminalData(faction : PlanetSideEmpire.Value,
- unk : Int = 0
- ) extends ConstructorData {
- override def bitsize : Long = 24L
-}
-
-object CommonTerminalData extends Marshallable[CommonTerminalData] {
- /**
- * Overloaded constructor for a type of common terminal.
- * @param cls the code for the type of object being constructed
- * @param guid the GUID this object will be assigned
- * @param parentSlot a parent-defined slot identifier that explains where the child is to be attached to the parent
- * @param terminal the `CommonTerminalData`
- * @return an `InternalSlot` object
- */
- def apply(cls : Int, guid : PlanetSideGUID, parentSlot : Int, terminal : CommonTerminalData) : InternalSlot =
- InternalSlot(cls, guid, parentSlot, terminal)
-
- implicit val codec : Codec[CommonTerminalData] = (
- ("faction" | PlanetSideEmpire.codec) ::
- uint2L ::
- ("unk" | uint2L) ::
- uint(18)
- ).exmap[CommonTerminalData] (
- {
- case fac :: 0 :: unk :: 0 :: HNil =>
- Attempt.successful(CommonTerminalData(fac, unk))
- case _ =>
- Attempt.failure(Err("invalid terminal data format"))
- },
- {
- case CommonTerminalData(fac, unk) =>
- Attempt.successful(fac :: 0 :: unk :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ConstructorData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ConstructorData.scala
index 6b91eb74..108d68d4 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ConstructorData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ConstructorData.scala
@@ -16,30 +16,32 @@ abstract class ConstructorData extends StreamBitSize
object ConstructorData {
/**
- * This pattern is intended to provide common conversion between all of the `Codec`s of the children of this class.
- * The casting will be performed through use of `exmap` in the child class.
- */
- type genericPattern = Option[ConstructorData]
-
- /**
- * Transform a `Codec[T]` for object type `T` into `ConstructorData.genericPattern`.
+ * Transform a `Codec[T]` for object type `T` into `ConstructorData`.
* @param objCodec a `Codec` that satisfies the transformation `Codec[T] -> T`
* @param objType a `String` that explains what the object should be identified as in the `Err` message;
* defaults to "object"
* @tparam T a subclass of `ConstructorData` that indicates what type the object is
- * @return `ConstructorData.genericPattern`
+ * @return `Codec[ConstructorData]`
*/
- def genericCodec[T <: ConstructorData](objCodec : Codec[T], objType : String = "object") : Codec[ConstructorData.genericPattern] =
- objCodec.exmap[ConstructorData.genericPattern] (
- {
- case x =>
- Attempt.successful(Some(x.asInstanceOf[ConstructorData]))
- },
- {
- case Some(x) =>
- Attempt.successful(x.asInstanceOf[T]) //why does this work? shouldn't type erasure be a problem?
- case _ =>
- Attempt.failure(Err(s"can not encode as $objType data"))
- }
- )
+ def apply[T <: ConstructorData](objCodec : Codec[T], objType : String = "object") : Codec[ConstructorData] =
+ objCodec.exmap[ConstructorData] (
+ x => {
+ try {
+ Attempt.successful(x.asInstanceOf[ConstructorData])
+ }
+ catch {
+ case ex : Exception =>
+ Attempt.failure(Err(s"can not cast decode of $x to $objType - $ex"))
+ }
+ },
+ x => {
+ try {
+ Attempt.successful(x.asInstanceOf[T]) //why does this work? shouldn't type erasure be a problem?
+ }
+ catch {
+ case ex : Exception =>
+ Attempt.failure(Err(s"can not cast encode $x to $objType - $ex"))
+ }
+ }
+ )
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ContainedTelepadDeployableData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ContainedTelepadDeployableData.scala
deleted file mode 100644
index 2d7ff06e..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ContainedTelepadDeployableData.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * na
- */
-final case class ContainedTelepadDeployableData(unk : Int,
- router_guid : PlanetSideGUID) extends ConstructorData {
- override def bitsize : Long = 59L
-}
-
-object ContainedTelepadDeployableData extends Marshallable[ContainedTelepadDeployableData] {
- implicit val codec : Codec[ContainedTelepadDeployableData] = (
- ("unk" | uint(7)) ::
- ("router_guid" | PlanetSideGUID.codec) ::
- uint16 ::
- uint4 ::
- uint16
- ).exmap[ContainedTelepadDeployableData] (
- {
- case unk :: rguid :: 0 :: 8 :: 0 :: HNil =>
- Attempt.successful(ContainedTelepadDeployableData(unk, rguid))
- case _ :: _ :: _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid rek data format"))
- },
- {
- case ContainedTelepadDeployableData(unk, rguid) =>
- Attempt.successful(unk :: rguid :: 0 :: 8 :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/Cosmetics.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/Cosmetics.scala
index da3f85b2..cd0ece4a 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/Cosmetics.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/Cosmetics.scala
@@ -4,6 +4,25 @@ package net.psforever.packet.game.objectcreate
import scodec.codecs._
import scodec.Codec
+/**
+ * Values for the different specific customizations available as cosmetics.
+ * `NoHelmet` removes the current helmet on the reinforced exo-suit and the agile exo-suit;
+ * other cosmetics require `no_helmet` to be `true` before they can be seen;
+ * `NoHelmet` does not override `Beret` or `BrimmedCap`
+ * `Beret` player dons a beret
+ * `Sunglasses` player dons sunglasses
+ * `Earpiece` player dons an earpiece on the left
+ * `BrimmedCap` player dons a cap;
+ * the cap overrides the beret, if both are selected
+ */
+object PersonalStyle extends Enumeration {
+ val BrimmedCap = Value(1)
+ val Earpiece = Value(2)
+ val Sunglasses = Value(4)
+ val Beret = Value(8)
+ val NoHelmet = Value(16)
+}
+
/**
* The different cosmetics that a player can apply to their character model's head.
*
@@ -11,31 +30,99 @@ import scodec.Codec
* These flags are only valid if the player has:
* for `DetailedCharacterData`, achieved at least battle rank twenty-four (battle experience points greater than 2286230),
* or, for `CharacterData`, achieved at least battle rank twenty-five (acquired their third uniform upgrade).
- * `CharacterData`, as implied, will not display these options until one battle rank after they would have become available.
- * @param no_helmet removes the current helmet on the reinforced exo-suit and the agile exo-suit;
- * all other cosmetics require `no_helmet` to be `true` before they can be seen
- * @param beret player dons a beret
- * @param sunglasses player dons sunglasses
- * @param earpiece player dons an earpiece on the left
- * @param brimmed_cap player dons a cap;
- * the cap overrides the beret, if both are selected
- * @see `UniformStyle.ThirdUpgrade`
+ * `CharacterData`, as suggested, will not display these options until one battle rank after they would have become available.
+ * @param pstyles a value that indicates certain cosmetic features by bitwise math
+ * @see `UniformStyle`
+ * @see `PersonalStyleFeatures`
*/
-final case class Cosmetics(no_helmet : Boolean,
- beret : Boolean,
- sunglasses : Boolean,
- earpiece : Boolean,
- brimmed_cap : Boolean
- ) extends StreamBitSize {
+final case class Cosmetics(pstyles : Int) extends StreamBitSize {
override def bitsize : Long = 5L
+
+ /**
+ * Transform the accumulated bitwise cosmetic feature integer into a group of all valid cosmetic feature values.
+ * @return a group of all valid cosmetic feature values
+ */
+ def Styles : Set[PersonalStyle.Value] = {
+ (for {
+ style <- PersonalStyle.values.toList
+ if (pstyles & style.id) == style.id
+ } yield style) toSet
+ }
+
+ /**
+ * Allocate a cosmetic feature to an existing group of cosmetic feature values if that feature is not already a member.
+ * `Cosmetics` is an immutable object so a new object with the additional value must be created.
+ * @param pstyle the cosmetic feature value
+ * @return a new `Cosmetics` object, potentially including the new cosmetic feature
+ */
+ def +(pstyle : PersonalStyle.Value) : Cosmetics = {
+ Cosmetics(pstyles | pstyle.id)
+ }
+
+ /**
+ * Revoke a cosmetic feature from an existing group of cosmetic feature values if that feature is a member.
+ * * `Cosmetics` is an immutable object so a new object with the value removed must be created.
+ * @param pstyle the cosmetic feature value
+ * @return a new `Cosmetics` object, excluding the new cosmetic feature
+ */
+ def -(pstyle : PersonalStyle.Value) : Cosmetics = {
+ Cosmetics(pstyles - (pstyles & pstyle.id))
+ }
+
+ /**
+ * Determine if this `Cosmetics` object contain the given cosmetic feature.
+ * @param pstyle the cosmetic feature value
+ * @return `true`, if the feature is included; `false`, otherwise
+ */
+ def contains(pstyle : PersonalStyle.Value) : Boolean = (pstyles & pstyle.id) == pstyle.id
}
object Cosmetics {
- implicit val codec : Codec[Cosmetics] = (
- ("no_helmet" | bool) ::
- ("beret" | bool) ::
- ("sunglasses" | bool) ::
- ("earpiece" | bool) ::
- ("brimmed_cap" | bool)
- ).as[Cosmetics]
+ /**
+ * Overloaded constructor for `Cosmetics` that loads no option.
+ * @return a `Cosmetics` object
+ */
+ def apply() : Cosmetics = Cosmetics(0)
+
+ /**
+ * Overloaded constructor for `Cosmetics` that loads a single option.
+ * @param pstyle the cosmetic feature that will be valid
+ * @return a `Cosmetics` object
+ */
+ def apply(pstyle : PersonalStyle.Value) : Cosmetics = Cosmetics(pstyle.id)
+
+ /**
+ * Overloaded constructor for `Cosmetics` that loads all options listed.
+ * @param pstyle all of the cosmetic feature that will be valid
+ * @return a `Cosmetics` object
+ */
+ def apply(pstyle : Set[PersonalStyle.Value]) : Cosmetics = {
+ Cosmetics(pstyle.foldLeft(0)(_ + _.id))
+ }
+
+ /**
+ * Overloaded constructor for `Cosmetics` that list all options as boolean values
+ * @param no_helmet removes the current helmet on the reinforced exo-suit and the agile exo-suit
+ * @param beret player dons a beret
+ * @param sunglasses player dons sunglasses
+ * @param earpiece player dons an earpiece on the left
+ * @param brimmed_cap player dons a cap
+ * @return a `Cosmetics` object
+ */
+ def apply(no_helmet : Boolean,
+ beret : Boolean,
+ sunglasses : Boolean,
+ earpiece : Boolean,
+ brimmed_cap : Boolean) : Cosmetics = {
+ implicit def bool2int(b : Boolean) : Int = if(b) 1 else 0
+ Cosmetics(
+ (no_helmet * 16) +
+ (beret * 8) +
+ (sunglasses * 4) +
+ (earpiece * 2) +
+ brimmed_cap
+ )
+ }
+
+ implicit val codec : Codec[Cosmetics] = uint(5).hlist.as[Cosmetics]
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedACEData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedACEData.scala
deleted file mode 100644
index 0c1ad166..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedACEData.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of an adaptive construction engine (ACE).
- * This one-time-use item deploys a variety of utilities into the game environment.
- * Has an advanced version internally called an `advanced_ace` and commonly called a Field Deployment Unit (FDU).
- * @param unk na
- */
-final case class DetailedACEData(unk : Int) extends ConstructorData {
- override def bitsize : Long = 51L
-}
-
-object DetailedACEData extends Marshallable[DetailedACEData] {
- implicit val codec : Codec[DetailedACEData] = (
- ("unk" | uint4L) ::
- uint4L ::
- uintL(20) ::
- uint4L ::
- uint16L ::
- uint(3)
- ).exmap[DetailedACEData] (
- {
- case code :: 8 :: 0 :: 2 :: 0 :: 4 :: HNil =>
- Attempt.successful(DetailedACEData(code))
- case _ =>
- Attempt.failure(Err("invalid ace data format"))
- },
- {
- case DetailedACEData(code) =>
- Attempt.successful(code :: 8 :: 0 :: 2 :: 0 :: 4 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedAmmoBoxData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedAmmoBoxData.scala
index 794ccf23..f430de8a 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedAmmoBoxData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedAmmoBoxData.scala
@@ -3,6 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
@@ -15,14 +16,17 @@ import shapeless.{::, HNil}
* The maximum amount of ammunition that can be stored in a single box is 65535 units.
* Regardless of the interface, however, the number will never be fully visible.
* Only the first three digits or the first four digits may be represented.
- * @param unk na
+ * @param data na
* @param magazine the number of rounds available
- * @see DetailedWeaponData
+ * @see `DetailedWeaponData`
*/
-final case class DetailedAmmoBoxData(unk : Int,
+final case class DetailedAmmoBoxData(data : CommonFieldData,
magazine : Int
) extends ConstructorData {
- override def bitsize : Long = 40L
+ override def bitsize : Long = {
+ val dataSize = data.bitsize
+ 17L + dataSize
+ }
}
object DetailedAmmoBoxData extends Marshallable[DetailedAmmoBoxData] {
@@ -37,22 +41,27 @@ object DetailedAmmoBoxData extends Marshallable[DetailedAmmoBoxData] {
def apply(cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : InternalSlot =
new InternalSlot(cls, guid, parentSlot, ammo)
+ def apply(unk : Int, mag : Int) : DetailedAmmoBoxData = {
+ DetailedAmmoBoxData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, unk > 0, None, false, None, None, PlanetSideGUID(0)), mag
+ )
+ }
+
implicit val codec : Codec[DetailedAmmoBoxData] = (
- uint4L ::
- ("unk" | uint4L) :: // 8 - common - 4 - safe, 2 - stream misalignment, 1 - safe, 0 - common
- uint(15) ::
+ ("data" | CommonFieldData.codec) ::
("magazine" | uint16L) ::
bool
).exmap[DetailedAmmoBoxData] (
{
- case 0xC :: unk :: 0 :: mag :: false :: HNil =>
- Attempt.successful(DetailedAmmoBoxData(unk, mag))
- case _ =>
- Attempt.failure(Err("invalid ammunition data format"))
+ case data :: mag :: false :: HNil =>
+ Attempt.successful(DetailedAmmoBoxData(data, mag))
+
+ case data =>
+ Attempt.failure(Err(s"invalid detailed ammunition data format - $data"))
},
{
- case DetailedAmmoBoxData(unk, mag) =>
- Attempt.successful(0xC :: unk :: 0 :: mag :: false:: HNil)
+ case DetailedAmmoBoxData(data, mag) =>
+ Attempt.successful(data :: mag :: false:: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedBoomerTriggerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedBoomerTriggerData.scala
deleted file mode 100644
index 3e4aebf7..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedBoomerTriggerData.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of the detonater utility that is created when putting down a Boomer with an ACE.
- */
-final case class DetailedBoomerTriggerData() extends ConstructorData {
- override def bitsize : Long = 51L
-}
-
-object DetailedBoomerTriggerData extends Marshallable[DetailedBoomerTriggerData] {
- implicit val codec : Codec[DetailedBoomerTriggerData] = (
- uint8L ::
- uint(22) ::
- bool :: //true
- uint(17) ::
- bool :: //true
- uint2L
- ).exmap[DetailedBoomerTriggerData] (
- {
- case 0xC8 :: 0 :: true :: 0 :: true :: 0 :: HNil =>
- Attempt.successful(DetailedBoomerTriggerData())
- case _ :: _ :: _ :: _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid command detonater format"))
- },
- {
- case DetailedBoomerTriggerData() =>
- Attempt.successful(0xC8 :: 0 :: true :: 0 :: true :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedCommandDetonaterData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedCommandDetonaterData.scala
index cd5c684b..7e50e19d 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedCommandDetonaterData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedCommandDetonaterData.scala
@@ -7,32 +7,32 @@ import scodec.codecs._
import shapeless.{::, HNil}
/**
- * A representation of the command uplink device.
- * I don't know much about the command uplink device so someone else has to provide this commentary.
+ * A representation of the command uplink device.
*/
-final case class DetailedCommandDetonaterData(unk1 : Int = 8,
- unk2 : Int = 0) extends ConstructorData {
- override def bitsize : Long = 51L
+final case class DetailedCommandDetonaterData(data : CommonFieldData) extends ConstructorData {
+ override def bitsize : Long = {
+ val dataSize = data.bitsize
+ 28L + dataSize
+ }
}
object DetailedCommandDetonaterData extends Marshallable[DetailedCommandDetonaterData] {
implicit val codec : Codec[DetailedCommandDetonaterData] = (
- ("unk1" | uint4L) ::
- ("unk2" | uint4L) ::
- uint(20) ::
- uint4L ::
+ ("data" | CommonFieldData.codec) ::
+ uint8 ::
uint16 ::
- uint(3)
+ uint4
).exmap[DetailedCommandDetonaterData] (
{
- case unk1 :: unk2 :: 0 :: 2 :: 0 :: 4 :: HNil =>
- Attempt.successful(DetailedCommandDetonaterData(unk1, unk2))
- case _ =>
- Attempt.failure(Err("invalid command detonator data format"))
+ case data :: 1 :: 0 :: 4 :: HNil =>
+ Attempt.successful(DetailedCommandDetonaterData(data))
+
+ case data =>
+ Attempt.failure(Err(s"invalid detailed command detonater data format - $data"))
},
{
- case DetailedCommandDetonaterData(unk1, unk2) =>
- Attempt.successful(unk1 :: unk2 :: 0 :: 2 :: 0 :: 4 :: HNil)
+ case DetailedCommandDetonaterData(data) =>
+ Attempt.successful(data :: 1 :: 0 :: 4 :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedConstructionToolData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedConstructionToolData.scala
new file mode 100644
index 00000000..5fc89bc0
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedConstructionToolData.scala
@@ -0,0 +1,37 @@
+// Copyright (c) 2018 PSForever
+package net.psforever.packet.game.objectcreate
+
+import net.psforever.packet.Marshallable
+import scodec.codecs._
+import scodec.{Attempt, Codec, Err}
+import shapeless.{::, HNil}
+
+/**
+ * `DetailedACEData` - `data.faction` is faction affinity, `data.unk1` is `true`
+ * `DetailedBoomerTriggerData` - `data.faction` can be `NEUTRAL`, `data.unk1` is `true`
+ * `DetailedTelepadData` - `data.faction` can be `NEUTRAL`, `data.jammered` is the router's GUID
+ */
+final case class DetailedConstructionToolData(data : CommonFieldData) extends ConstructorData {
+ override def bitsize : Long = 28L + data.bitsize
+}
+
+object DetailedConstructionToolData extends Marshallable[DetailedConstructionToolData] {
+ implicit val codec : Codec[DetailedConstructionToolData] = (
+ ("data" | CommonFieldData.codec(false)) ::
+ uint8 ::
+ uint(18) ::
+ uint2
+ ).exmap[DetailedConstructionToolData] (
+ {
+ case data :: 1 :: 1 :: _ :: HNil =>
+ Attempt.successful(DetailedConstructionToolData(data))
+ case data =>
+ Attempt.failure(Err(s"invalid detailed construction tool data format - $data"))
+ },
+ {
+ case DetailedConstructionToolData(data) =>
+ Attempt.successful(data :: 1 :: 1 :: 0 :: HNil)
+ }
+ )
+}
+
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedLockerContainerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedLockerContainerData.scala
index cae75cd8..beda8df1 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedLockerContainerData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedLockerContainerData.scala
@@ -3,6 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
import scodec.codecs._
import scodec.{Attempt, Codec, Err}
import shapeless.{::, HNil}
@@ -14,10 +15,10 @@ import shapeless.{::, HNil}
* the actual container for them, in grid format, can only be accessed by interacting with locker objects in the game world.
* Items are generally added and removed in the same way as with any other opened inventory.
* Unlike other inventories, however, locker space is personal to an avatar and can not be accessed by other players.
- * @param unk na
+ * @param data na
* @param inventory the items in this inventory
*/
-final case class DetailedLockerContainerData(unk : Int,
+final case class DetailedLockerContainerData(data : CommonFieldData,
inventory : Option[InventoryData]
) extends ConstructorData {
override def bitsize : Long = {
@@ -34,7 +35,7 @@ object DetailedLockerContainerData extends Marshallable[DetailedLockerContainerD
* @return a `DetailedLockerContainerData` object
*/
def apply(unk : Int) : DetailedLockerContainerData =
- new DetailedLockerContainerData(unk, None)
+ new DetailedLockerContainerData(CommonFieldData(PlanetSideEmpire.NEUTRAL, unk), None)
/**
* Overloaded constructor for creating `DetailedLockerContainerData` containing known items.
@@ -43,7 +44,7 @@ object DetailedLockerContainerData extends Marshallable[DetailedLockerContainerD
* @return a `DetailedLockerContainerData` object
*/
def apply(unk : Int, inventory : List[InternalSlot]) : DetailedLockerContainerData =
- new DetailedLockerContainerData(unk, Some(InventoryData(inventory)))
+ new DetailedLockerContainerData(CommonFieldData(PlanetSideEmpire.NEUTRAL, unk), Some(InventoryData(inventory)))
/**
* Overloaded constructor for creating `DetailedLockerContainerData` while masking use of `InternalSlot`.
@@ -57,27 +58,26 @@ object DetailedLockerContainerData extends Marshallable[DetailedLockerContainerD
new InternalSlot(cls, guid, parentSlot, locker)
implicit val codec : Codec[DetailedLockerContainerData] = (
- uint4L ::
- ("unk" | uint4L) :: // 8 - common - 4 - safe, 2 - stream misalignment, 1 - safe, 0 - common
- uint(15) ::
+ ("data" | CommonFieldData.codec) ::
uint16L :: //always 1
optional(bool, InventoryData.codec_detailed)
).exmap[DetailedLockerContainerData] (
{
- case 0xC :: unk :: 0 :: 1 :: None :: HNil =>
- Attempt.successful(DetailedLockerContainerData(unk, None))
+ case data :: 1 :: None :: HNil =>
+ Attempt.successful(DetailedLockerContainerData(data, None))
- case 0xC :: unk :: 0 :: 1 :: Some(inv) :: HNil =>
- Attempt.successful(DetailedLockerContainerData(unk, Some(inv)))
- case _ =>
- Attempt.failure(Err(s"invalid locker container data format"))
+ case data :: 1 :: Some(inv) :: HNil =>
+ Attempt.successful(DetailedLockerContainerData(data, Some(inv)))
+
+ case data =>
+ Attempt.failure(Err(s"invalid detailed locker container data format - $data"))
},
{
- case DetailedLockerContainerData(unk, None) =>
- Attempt.successful(0xC :: unk :: 0 :: 1 :: None :: HNil)
+ case DetailedLockerContainerData(data, None) =>
+ Attempt.successful(data :: 1 :: None :: HNil)
- case DetailedLockerContainerData(unk, Some(inv)) =>
- Attempt.successful(0xC :: unk :: 0 :: 1 :: Some(inv) :: HNil)
+ case DetailedLockerContainerData(data, Some(inv)) =>
+ Attempt.successful(data :: 1 :: Some(inv) :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedPlayerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedPlayerData.scala
index c4778dba..e4788bb5 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedPlayerData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedPlayerData.scala
@@ -60,7 +60,7 @@ object DetailedPlayerData extends Marshallable[DetailedPlayerData] {
* technically, always `DrawnSlot.None`, but the field is preserved to maintain similarity
* @return a `DetailedPlayerData` object
*/
- def apply(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Option[Int])=>DetailedCharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
+ def apply(basic_appearance : Int=>CharacterAppearanceData, character_data : Option[Int]=>DetailedCharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
val appearance = basic_appearance(5)
DetailedPlayerData(None, appearance, character_data(appearance.altModelBit), Some(inventory), drawn_slot)(false)
}
@@ -75,7 +75,7 @@ object DetailedPlayerData extends Marshallable[DetailedPlayerData] {
* technically, always `DrawnSlot.None`, but the field is preserved to maintain similarity
* @return a `DetailedPlayerData` object
*/
- def apply(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Option[Int])=>DetailedCharacterData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
+ def apply(basic_appearance : Int=>CharacterAppearanceData, character_data : Option[Int]=>DetailedCharacterData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
val appearance = basic_appearance(5)
DetailedPlayerData(None, appearance, character_data(appearance.altModelBit), None, drawn_slot)(false)
}
@@ -91,7 +91,7 @@ object DetailedPlayerData extends Marshallable[DetailedPlayerData] {
* @param drawn_slot the holster that is depicted as exposed, or "drawn"
* @return a `DetailedPlayerData` object
*/
- def apply(pos : PlacementData, basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Option[Int])=>DetailedCharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
+ def apply(pos : PlacementData, basic_appearance : Int=>CharacterAppearanceData, character_data : Option[Int]=>DetailedCharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
val appearance = basic_appearance(PlayerData.PaddingOffset(Some(pos)))
DetailedPlayerData(Some(pos), appearance, character_data(appearance.altModelBit), Some(inventory), drawn_slot)(true)
}
@@ -106,7 +106,7 @@ object DetailedPlayerData extends Marshallable[DetailedPlayerData] {
* @param drawn_slot the holster that is depicted as exposed, or "drawn"
* @return a `DetailedPlayerData` object
*/
- def apply(pos : PlacementData, basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Option[Int])=>DetailedCharacterData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
+ def apply(pos : PlacementData, basic_appearance : Int=>CharacterAppearanceData, character_data : Option[Int]=>DetailedCharacterData, drawn_slot : DrawnSlot.Value) : DetailedPlayerData = {
val appearance = basic_appearance(PlayerData.PaddingOffset(Some(pos)))
DetailedPlayerData(Some(pos), appearance, character_data(appearance.altModelBit), None, drawn_slot)(true)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedREKData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedREKData.scala
index c4c19e62..583e320a 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedREKData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedREKData.scala
@@ -11,34 +11,36 @@ import shapeless.{::, HNil}
* This data will help construct the "tool" called a Remote Electronics Kit.
*
* Of note is the first portion of the data which resembles the `DetailedWeaponData` format.
- * @param unk1 na
- * @param unk2 na
+ * @param data na
+ * @param unk na
*/
-final case class DetailedREKData(unk1 : Int,
- unk2 : Int = 0
+final case class DetailedREKData(data : CommonFieldData,
+ unk : Int = 0
) extends ConstructorData {
- override def bitsize : Long = 67L
+ override def bitsize : Long = {
+ val dataSize = data.bitsize
+ 43L + dataSize
+ }
}
object DetailedREKData extends Marshallable[DetailedREKData] {
implicit val codec : Codec[DetailedREKData] = (
- ("unk" | uint4L) ::
- uint4L ::
- uintL(20) ::
- uint4L ::
+ ("data" | CommonFieldData.codec2) ::
+ uint8 ::
uint16L ::
uint4L ::
- ("unk2" | uintL(15))
+ ("unk" | uint8) ::
+ uint(7)
).exmap[DetailedREKData] (
{
- case code :: 8 :: 0 :: 2 :: 0 :: 8 :: unk2 :: HNil =>
- Attempt.successful(DetailedREKData(code, unk2))
- case _ =>
- Attempt.failure(Err("invalid rek data format"))
+ case data :: 2 :: 0 :: 8 :: unk :: 0 :: HNil =>
+ Attempt.successful(DetailedREKData(data, unk))
+ case data =>
+ Attempt.failure(Err(s"invalid detailed rek data format - $data"))
},
{
- case DetailedREKData(code, unk2) =>
- Attempt.successful(code :: 8 :: 0 :: 2 :: 0 :: 8 :: unk2 :: HNil)
+ case DetailedREKData(data, unk) =>
+ Attempt.successful(data :: 2 :: 0 :: 8 :: unk :: 0 :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedTelepadData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedTelepadData.scala
deleted file mode 100644
index 230fb666..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedTelepadData.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of the telepad portion of `ObjectCreateDetailedMessage` packet data.
- * This data will help construct the "cosntruction tool"
- * that can be obtained from the Router vehicle - the Router telepad.
- * It issued to construct a bidirectional teleportation point associated with a Router if that Router is deployed.
- * @param unk na
- * @param router_guid the Router
- */
-final case class DetailedTelepadData(unk : Int, router_guid : Option[PlanetSideGUID]) extends ConstructorData {
- override def bitsize : Long = {
- val rguidSize = if(router_guid.nonEmpty) 16 else 0
- 51L + rguidSize
- }
-}
-
-object DetailedTelepadData extends Marshallable[DetailedTelepadData] {
- def apply(unk : Int) : DetailedTelepadData = DetailedTelepadData(unk, None)
-
- def apply(unk : Int, router_guid : PlanetSideGUID) : DetailedTelepadData = DetailedTelepadData(unk, Some(router_guid))
-
- implicit val codec : Codec[DetailedTelepadData] = (
- ("unk" | uint(6)) ::
- optional(bool, "router_guid" | PlanetSideGUID.codec) ::
- uint(24) ::
- uint(18) ::
- uint2
- ).exmap[DetailedTelepadData] (
- {
- case unk :: rguid :: 1 :: 1 :: 0 :: HNil =>
- Attempt.successful(DetailedTelepadData(unk, rguid))
- case _ =>
- Attempt.failure(Err("invalid detailed telepad format"))
- },
- {
- case DetailedTelepadData(unk, rguid) =>
- Attempt.successful(unk :: rguid :: 1 :: 1 :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala
index ba55ad81..cc9e997c 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala
@@ -3,6 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
@@ -14,29 +15,21 @@ import shapeless.{::, HNil}
* The data for the weapons nests information for the default (current) type and number of ammunition in its magazine.
* This ammunition data essentially is the weapon's magazines as numbered slots.
* An "expected" number of ammunition slot data can be passed into the function.
- * @param unk1 na
- * @param unk2 na
+ * @param data field common to multiple game objects
+ * @param fire_mode the current fire mode
* @param ammo data regarding the currently loaded ammunition type(s) and quantity(ies)
- * @param mag_capacity implicit;
- * the total number of concurrently-loaded ammunition types allowed in this weapon;
- * concurrent ammunition does not need to be unloaded to be switched;
- * defaults to 1;
- * 0 is invalid;
- * -1 or less ignores the imposed checks
* @see `DetailedAmmoBoxData`
* @see `WeaponData`
*/
-final case class DetailedWeaponData(unk1 : Int,
- unk2 : Int,
+final case class DetailedWeaponData(data : CommonFieldData,
fire_mode : Int,
- ammo : List[InternalSlot]
- )(implicit val mag_capacity : Int = 1) extends ConstructorData {
+ ammo : List[InternalSlot],
+ unk : Boolean = false
+ ) extends ConstructorData {
override def bitsize : Long = {
- var bitsize : Long = 0L
- for(o <- ammo) {
- bitsize += o.bitsize
- }
- 61L + bitsize //51 + 10 (from InventoryData) + ammo
+ val dataSize = data.bitsize
+ val ammoSize : Long = ammo.foldLeft(0L)(_ + _.bitsize)
+ 38L + dataSize + ammoSize //28 + 10 (from InventoryData) + ammo
}
}
@@ -51,8 +44,23 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] {
* @param ammo the constructor data for the ammunition
* @return a `DetailedWeaponData` object
*/
- def apply(unk1 : Int, unk2 : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData =
- new DetailedWeaponData(unk1, unk2, 0, InternalSlot(cls, guid, parentSlot, ammo) :: Nil)
+ def apply(unk1 : Int, unk2 : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData = {
+ DetailedWeaponData(
+ CommonFieldData(
+ PlanetSideEmpire(unk1 & 3),
+ false,
+ false,
+ (unk2 & 8) == 8,
+ None,
+ (unk2 & 4) == 4,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ 0,
+ List(InternalSlot(cls, guid, parentSlot, ammo))
+ )
+ }
/**
@@ -65,71 +73,58 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] {
* @param ammo the constructor data for the ammunition
* @return a `DetailedWeaponData` object
*/
- def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData =
- new DetailedWeaponData(unk1, unk2, fire_mode, InternalSlot(cls, guid, parentSlot, ammo) :: Nil)
+ def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData = {
+ DetailedWeaponData(
+ CommonFieldData(
+ PlanetSideEmpire(unk1 & 3),
+ false,
+ false,
+ (unk2 & 8) == 8,
+ None,
+ (unk2 & 4) == 4,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ fire_mode,
+ List(InternalSlot(cls, guid, parentSlot, ammo))
+ )
+ }
- /**
- * A `Codec` for `DetailedWeaponData`
- * @param mag_capacity the total number of concurrently-loaded ammunition types allowed in this weapon;
- * defaults to 1
- * @return a `WeaponData` object or a `BitVector`
- */
- def codec(mag_capacity : Int = 1) : Codec[DetailedWeaponData] = (
- ("unk1" | uint(3)) ::
- bool :: //weapon refuses to shoot if set (not weapons lock?)
- ("unk2" | uint4L) :: //8 - common; 4 - jammers weapons; 2 - weapon breaks; 1, 0 - safe
- uint24 ::
- uint(12) ::
- ("fire_mode" | uint(3)) :: //TODO size?
- uint(3) ::
- ("ammo" | InventoryData.codec_detailed) ::
- bool
+ implicit val codec : Codec[DetailedWeaponData] = (
+ ("data" | CommonFieldData.codec) ::
+ uint8 ::
+ uint8 ::
+ ("fire_mode" | uint8) ::
+ uint2 ::
+ optional(bool, "ammo" | InventoryData.codec_detailed) ::
+ ("unk" | bool)
).exmap[DetailedWeaponData] (
{
- case unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil =>
+ case data :: 1 :: 0 :: fmode :: 1 :: Some(InventoryData(ammo)) :: unk :: HNil =>
val magSize = ammo.size
- if(mag_capacity == 0 || magSize == 0) {
+ if(magSize == 0) {
Attempt.failure(Err("weapon must decode some ammunition"))
}
- else if(mag_capacity > 0 && magSize != mag_capacity) {
- Attempt.failure(Err(s"weapon decodes too much or too little ammunition - actual $magSize, expected $mag_capacity"))
- }
else {
- Attempt.successful(DetailedWeaponData(unk1, unk2, fmode, ammo)(magSize))
+ Attempt.successful(DetailedWeaponData(data, fmode, ammo, unk))
}
- case _ =>
- Attempt.failure(Err("invalid weapon data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid weapon data format - $data"))
},
{
- case obj @ DetailedWeaponData(unk1, unk2, fmode, ammo) =>
+ case DetailedWeaponData(data, fmode, ammo, unk) =>
val magSize = ammo.size
- val magCapacity = obj.mag_capacity
- if(mag_capacity == 0 || magCapacity == 0 || magSize == 0) {
+ if(magSize == 0) {
Attempt.failure(Err("weapon must encode some ammunition"))
}
- else if(magCapacity < 0 || mag_capacity < 0) {
- Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil)
+ else if(magSize >= 255) {
+ Attempt.failure(Err("weapon encodes too much ammunition (255+ types!)"))
}
else {
- if(magCapacity != mag_capacity) {
- Attempt.failure(Err(s"different encoding expectations for amount of ammunition - actual $magCapacity, expected $mag_capacity"))
- }
- else if(magSize != mag_capacity) {
- Attempt.failure(Err(s"weapon encodes wrong amount of ammunition - actual $magSize, expected $mag_capacity"))
- }
- else if(magSize >= 255) {
- Attempt.failure(Err("weapon encodes too much ammunition (255+ types!)"))
- }
- else {
- Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil)
- }
+ Attempt.successful(data :: 1 :: 0 :: fmode :: 1 :: Some(InventoryData(ammo)) :: unk :: HNil)
}
-
- case _ =>
- Attempt.failure(Err("invalid weapon data format"))
}
)
-
- implicit val codec : Codec[DetailedWeaponData] = codec()
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppedItemData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppedItemData.scala
index e65cab16..267d926d 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppedItemData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppedItemData.scala
@@ -17,7 +17,7 @@ final case class DroppedItemData[T <: ConstructorData](pos : PlacementData, obj
object DroppedItemData {
/**
- * Transform `DroppedItemData[T]` for object type `T` into `ConstructorData.genericPattern`.
+ * Transform `DroppedItemData[T]` for object type `T` into `ConstructorData`.
*
* This function eliminates the need to have a separate "DroppedFooData" class for every object "Foo."
* Two functions normally perform this transformation: an `implicit` `codec` used in a `genericCodec`.
@@ -32,10 +32,10 @@ object DroppedItemData {
* @param objType a `String` that explains what the object should be identified as in the log;
* defaults to "object"
* @tparam T a subclass of `ConstructorData` that indicates what type the object is
- * @return `ConstructorData.genericPattern`
- * @see `ConstructorData.genericPattern` (function)
+ * @return `Codec[ConstructorData]`
+ * @see `ConstructorData` (function)
*/
- def genericCodec[T <: ConstructorData](objCodec : Codec[T], objType : String = "object") : Codec[ConstructorData.genericPattern] = (
+ def apply[T <: ConstructorData](objCodec : Codec[T], objType : String = "object") : Codec[ConstructorData] = (
("pos" | PlacementData.codec) ::
("obj" | objCodec)
).xmap[DroppedItemData[T]] (
@@ -47,16 +47,24 @@ object DroppedItemData {
case DroppedItemData(pos, obj) =>
pos :: obj :: HNil
}
- ).exmap[ConstructorData.genericPattern] (
- {
- case x =>
- Attempt.successful(Some(x.asInstanceOf[ConstructorData]))
+ ).exmap[ConstructorData] (
+ x => {
+ try {
+ Attempt.successful(x.asInstanceOf[ConstructorData])
+ }
+ catch {
+ case ex : Exception =>
+ Attempt.failure(Err(s"can not cast decode of $x to dropped $objType - $ex"))
+ }
},
- {
- case Some(x) =>
- Attempt.successful(x.asInstanceOf[DroppedItemData[T]])
- case _ =>
- Attempt.failure(Err(s"can not encode dropped $objType data"))
+ x => {
+ try {
+ Attempt.successful(x.asInstanceOf[DroppedItemData[T]]) //why does this work? shouldn't type erasure be a problem?
+ }
+ catch {
+ case ex : Exception =>
+ Attempt.failure(Err(s"can not cast encode $x to dropped $objType - $ex"))
+ }
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppodData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppodData.scala
index 9ad295b0..6d7006a9 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppodData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DroppodData.scala
@@ -3,7 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import scodec.codecs._
-import scodec.{Attempt, Codec}
+import scodec.{Attempt, Codec, Err}
import shapeless.{::, HNil}
/**
@@ -31,7 +31,7 @@ import shapeless.{::, HNil}
* @see `DroppodLaunchRequestMessage`
* @see `DroppodLaunchResponseMessage`
*/
-final case class DroppodData(basic : CommonFieldData,
+final case class DroppodData(basic : CommonFieldDataWithPlacement,
burn : Boolean = false,
health : Int = 255
) extends ConstructorData {
@@ -43,7 +43,7 @@ final case class DroppodData(basic : CommonFieldData,
object DroppodData extends Marshallable[DroppodData] {
implicit val codec : Codec[DroppodData] = (
- ("basic" | CommonFieldData.codec) ::
+ ("basic" | CommonFieldDataWithPlacement.codec) ::
bool ::
("health" | uint8L) :: //health
uintL(5) :: //0x0
@@ -56,6 +56,9 @@ object DroppodData extends Marshallable[DroppodData] {
case basic :: false :: health :: 0 :: 0xF :: 0 :: boosters :: false :: HNil =>
val burn : Boolean = boosters == 0
Attempt.successful(DroppodData(basic, burn, health))
+
+ case data =>
+ Attempt.failure(Err(s"invalid droppod data format - $data"))
},
{
case DroppodData(basic, burn, health) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/HandheldData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/HandheldData.scala
new file mode 100644
index 00000000..9cd6e5e0
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/HandheldData.scala
@@ -0,0 +1,46 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.packet.game.objectcreate
+
+import net.psforever.packet.Marshallable
+import scodec.{Attempt, Codec, Err}
+import scodec.codecs._
+import shapeless.{::, HNil}
+
+/**
+ * A representation of a number of simplified objects that the user can hold in their hands, including:
+ * the advanced construction engine (`ace`),
+ * the field deployable unit (`advanced_ace`),
+ * the boomer trigger apparatus,
+ * the remote telepad (not deployed),
+ * the flail laser pointer (`flail_targeting_laser`),
+ * and the command uplink device (`command_detonater`).
+ * @param data fields that are common to this game object
+ * - v4 - not used, i.e., the simple format `CommonFieldData` object is employed
+ * - v5 - for the telepad, this field is expected to be the GUID of the associated Router
+ */
+final case class HandheldData(data : CommonFieldData) extends ConstructorData {
+ override def bitsize : Long = {
+ 11L + data.bitsize
+ }
+}
+
+object HandheldData extends Marshallable[HandheldData] {
+ implicit val codec : Codec[HandheldData] = (
+ ("data" | CommonFieldData.codec) ::
+ uint4 ::
+ uint4 ::
+ uint(3)
+ ).exmap[HandheldData] (
+ {
+ case data :: 0 :: 0 :: 0 :: HNil =>
+ Attempt.successful(HandheldData(data))
+
+ case data =>
+ Attempt.failure(Err(s"invalid handheld tool data format - $data"))
+ },
+ {
+ case HandheldData(data) =>
+ Attempt.successful(data :: 0 :: 0 :: 0 :: HNil)
+ }
+ )
+}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/InternalSlot.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/InternalSlot.scala
index 012dacb7..c338490f 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/InternalSlot.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/InternalSlot.scala
@@ -45,12 +45,12 @@ object InternalSlot {
}
).xmap[InternalSlot] (
{
- case cls :: guid :: slot :: Some(obj) :: HNil =>
+ case cls :: guid :: slot :: obj :: HNil =>
InternalSlot(cls, guid, slot, obj)
},
{
case InternalSlot(cls, guid, slot, obj) =>
- cls :: guid :: slot :: Some(obj) :: HNil
+ cls :: guid :: slot :: obj :: HNil
}
)
@@ -65,12 +65,12 @@ object InternalSlot {
}
).xmap[InternalSlot] (
{
- case cls :: guid :: slot :: Some(obj) :: HNil =>
+ case cls :: guid :: slot :: obj :: HNil =>
InternalSlot(cls, guid, slot, obj)
},
{
case InternalSlot(cls, guid, slot, obj) =>
- cls :: guid :: slot :: Some(obj) :: HNil
+ cls :: guid :: slot :: obj :: HNil
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/LargeDeployableData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/LargeDeployableData.scala
index e2a63545..d332f428 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/LargeDeployableData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/LargeDeployableData.scala
@@ -7,19 +7,9 @@ import scodec.{Attempt, Codec, Err}
import shapeless.{::, HNil}
/**
- * A representation of the Spitfire-based small turrets deployed using an adaptive construction engine.
- *
- * The turret may contain substructure defining a weapon is a turret weapon contained within the turret itself.
- * Furthermore, that turret-like weapon is loaded with turret-like ammunition.
- * In other words, this outer turret can be considered a weapons platform for the inner turret weapon.
- *
- * If the turret has no `health`, it is rendered as destroyed.
- * If the turret has no internal weapon, it is safest rendered as destroyed.
- * @param deploy data common to objects spawned by the (advanced) adaptive construction engine
- * @param health the amount of health the object has, as a percentage of a filled bar
- * @param internals data regarding the mounted weapon
+ * This class currently is unused but is based on the `SmallTurretData` `Codec` class.
*/
-final case class LargeDeployableData(deploy : SmallDeployableData,
+final case class LargeDeployableData(deploy : CommonFieldDataWithPlacement,
health : Int,
internals : Option[InventoryData] = None
) extends ConstructorData {
@@ -37,7 +27,7 @@ final case class LargeDeployableData(deploy : SmallDeployableData,
object LargeDeployableData extends Marshallable[LargeDeployableData] {
implicit val codec : Codec[LargeDeployableData] = (
- ("deploy" | SmallDeployableData.codec) ::
+ ("deploy" | CommonFieldDataWithPlacement.codec2) ::
("health" | uint8L) ::
uintL(7) ::
uint4L ::
@@ -54,8 +44,9 @@ object LargeDeployableData extends Marshallable[LargeDeployableData] {
}
Attempt.successful(LargeDeployableData(deploy, newHealth, newInternals))
- case _ =>
- Attempt.failure(Err("invalid large deployable data format"))
+
+ case data =>
+ Attempt.failure(Err(s"invalid large deployable data format - $data"))
},
{
case LargeDeployableData(deploy, health, internals) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/LockerContainerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/LockerContainerData.scala
index 3cba5574..6bae06b1 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/LockerContainerData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/LockerContainerData.scala
@@ -12,27 +12,39 @@ import shapeless.{::, HNil}
* For whatever reason, these "lockers" are typically placed at the origin coordinates.
* @param inventory the items inside this locker
*/
-final case class LockerContainerData(inventory : InventoryData) extends ConstructorData {
- override def bitsize : Long = 105L + inventory.bitsize //81u + 2u + 21u + 1u
+final case class LockerContainerData(inventory : Option[InventoryData]) extends ConstructorData {
+ override def bitsize : Long = {
+ val base : Long = 105L
+ (inventory match {
+ case Some(inv) => inv.bitsize
+ case None => 0L
+ }) + base //81u + 2u + 21u + 1u
+ }
}
object LockerContainerData extends Marshallable[LockerContainerData] {
+ def apply() : LockerContainerData = new LockerContainerData(None)
+
+ def apply(inventory : InventoryData) : LockerContainerData = new LockerContainerData(Some(inventory))
+
+ def apply(inventory : List[InternalSlot]) : LockerContainerData = new LockerContainerData(Some(InventoryData(inventory)))
+
implicit val codec : Codec[LockerContainerData] = (
- uint32 :: uint32 :: uint(17) :: //can substitute with PlacementData, if ever necessary
+ uint32 :: uint32 :: uint(17) ::
uint2L ::
uint(21) ::
- bool ::
- InventoryData.codec
+ ("inventory" | optional(bool, InventoryData.codec))
).exmap[LockerContainerData] (
{
- case 0 :: 0 :: 0 :: 3 :: 0 :: true :: inv :: HNil =>
- Attempt.successful(LockerContainerData(inv))
- case _ =>
- Attempt.failure(Err("invalid locker container format"))
+ case 0 :: 0 :: 0 :: 3 :: 0 :: inventory :: HNil =>
+ Attempt.successful(LockerContainerData(inventory))
+
+ case data =>
+ Attempt.failure(Err(s"invalid locker container data format - $data"))
},
{
- case LockerContainerData(inv) =>
- Attempt.successful(0L :: 0L :: 0 :: 3 :: 0 :: true :: inv :: HNil)
+ case LockerContainerData(inventory) =>
+ Attempt.successful(0L :: 0L :: 0 :: 3 :: 0 :: inventory :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala
index c4766570..776d367c 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala
@@ -296,9 +296,20 @@ object ObjectClass {
final val portable_manned_turret_vs = 688
//projectiles
final val hunter_seeker_missile_projectile = 405
+ final val meteor_common = 543
+ final val meteor_projectile_b_large = 544
+ final val meteor_projectile_b_medium = 545
+ final val meteor_projectile_b_small = 546
+ final val meteor_projectile_large = 547
+ final val meteor_projectile_medium = 548
+ final val meteor_projectile_small = 549
+ final val oicw_little_buddy = 601
final val oicw_projectile = 602
+ final val radiator_cload = 717
+ final val sparrow_projectile = 792
final val starfire_projectile = 831
final val striker_missile_targeting_projectile = 841
+ final val wasp_rocket_projectile = 1001
//vehicles
final val apc_destroyed = 65
final val apc_tr = 67 //juggernaut
@@ -394,289 +405,289 @@ object ObjectClass {
* @return the `Codec` that handles the format of data for that particular item class, or a failing `Codec`
* @see `ConstructorData`
*/
- def selectDataDetailedCodec(objClass : Int) : Codec[ConstructorData.genericPattern] =
+ def selectDataDetailedCodec(objClass : Int) : Codec[ConstructorData] =
(objClass : @switch) match {
//ammunition
- case ObjectClass.bullet_105mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_12mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_150mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_15mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_20mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_25mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_35mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_75mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm_AP => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_combo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_vehicle => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.anniversary_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_immolation_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_laser_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_plasma_rocket_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_ppa_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_starfire_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_canister => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_siphon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.bolt => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.burster_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_100mm_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_burster_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_chaingun_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_cluster_bomb_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_tank_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.comet_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.dualcycler_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_cell => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_gun_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.falcon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.firebird_missile => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.flamethrower_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.flux_cannon_thresher_battery => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.fluxpod_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.frag_cartridge => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.frag_grenade_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.gauss_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.grenade => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.health_canister => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_grenade_mortar => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_rail_beam_battery => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.hellfire_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.hunter_seeker_missile => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.jammer_cartridge => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.jammer_grenade_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.lancer_cartridge => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.liberator_bomb => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.maelstrom_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.melee_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.mine => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.mine_sweeper_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.ntu_siphon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.oicw_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.pellet_gun_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_dual_machine_gun_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_mechhammer_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_particle_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_rocket_pod_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_sparrow_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.phalanx_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.phoenix_missile => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.plasma_cartridge => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.plasma_grenade_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.pounder_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.pulse_battery => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.quasar_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.reaver_rocket => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.rocket => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.scattercannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell_AP => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.six_shooter_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.skyguard_flak_cannon_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.sparrow_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_aa_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.starfire_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.striker_missile_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.trek_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.upgrade_canister => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_gun_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_rocket_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.winchester_ammo => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_105mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_12mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_150mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_15mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_20mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_25mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_35mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_75mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_9mm => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_9mm_AP => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.ancient_ammo_combo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.ancient_ammo_vehicle => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.anniversary_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.aphelion_immolation_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.aphelion_laser_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.aphelion_plasma_rocket_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.aphelion_ppa_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.aphelion_starfire_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.armor_canister => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.armor_siphon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.bolt => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.burster_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.colossus_100mm_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.colossus_burster_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.colossus_chaingun_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.colossus_cluster_bomb_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.colossus_tank_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.comet_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.dualcycler_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.energy_cell => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.energy_gun_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.falcon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.firebird_missile => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.flamethrower_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.flux_cannon_thresher_battery => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.fluxpod_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.frag_cartridge => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.frag_grenade_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.gauss_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.grenade => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.health_canister => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.heavy_grenade_mortar => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.heavy_rail_beam_battery => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.hellfire_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.hunter_seeker_missile => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.jammer_cartridge => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.jammer_grenade_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.lancer_cartridge => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.liberator_bomb => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.maelstrom_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.melee_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.mine => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.mine_sweeper_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.ntu_siphon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.oicw_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.pellet_gun_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.peregrine_dual_machine_gun_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.peregrine_mechhammer_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.peregrine_particle_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.peregrine_rocket_pod_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.peregrine_sparrow_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.phalanx_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.phoenix_missile => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.plasma_cartridge => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.plasma_grenade_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.pounder_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.pulse_battery => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.quasar_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.reaver_rocket => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.rocket => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.scattercannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.shotgun_shell => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.shotgun_shell_AP => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.six_shooter_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.skyguard_flak_cannon_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.sparrow_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.spitfire_aa_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.spitfire_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.starfire_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.striker_missile_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.trek_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.upgrade_canister => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.wasp_gun_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.wasp_rocket_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.winchester_ammo => ConstructorData(DetailedAmmoBoxData.codec, "ammo box")
//weapons
- case ObjectClass.beamer => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.cannon_dropship_20mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.anniversary_gun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.anniversary_guna => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.anniversary_gunb => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_ballgun_l => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_ballgun_r => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systema => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemb => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemc => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemc_nc => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemc_tr => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemc_vs => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemd => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemd_nc => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemd_tr => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.apc_weapon_systemd_vs => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_immolation_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_plasma_rocket_pod => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aurora_weapon_systema => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.aurora_weapon_systemb => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.battlewagon_weapon_systema => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.battlewagon_weapon_systemb => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.battlewagon_weapon_systemc => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.battlewagon_weapon_systemd => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.bolt_driver => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.chainblade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_cluster_bomb_pod => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_dual_100mm_cannons => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cycler => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.dropship_rear_turret => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.energy_gun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_nc => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_tr => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_vs => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.flail_weapon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.flamethrower => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.flechette => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.flux_cannon_thresher => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.fluxpod => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.forceblade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.fragmentation_grenade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.fury_weapon_systema => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.galaxy_gunship_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.galaxy_gunship_gun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.galaxy_gunship_tailgun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.gauss => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.gauss_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.grenade_launcher_marauder => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.heavy_rail_beam_magrider => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.heavy_sniper => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.hellfire => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.hunterseeker => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.ilc9 => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.isp => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.jammer_grenade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.katana => ConstructorData.genericCodec(DetailedWeaponData.codec(2), "weapon")
- case ObjectClass.lancer => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.lasher => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.liberator_25mm_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.liberator_bomb_bay => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.liberator_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.lightgunship_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.lightning_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.maelstrom => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.magcutter => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.mediumtransport_weapon_systemA => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.mediumtransport_weapon_systemB => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.mini_chaingun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.oicw => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.nchev_falcon => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.nchev_scattercannon => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.nchev_sparrow => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
-// case ObjectClass.particle_beam_magrider => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_rocket_pods => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_particle_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow_left => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow_right => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.phalanx_avcombo => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.phalanx_flakcombo => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.phalanx_sgl_hevgatcan => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.phoenix => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.prowler_weapon_systemA => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.prowler_weapon_systemB => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.plasma_grenade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.pulsar => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.pulsed_particle_accelerator => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.punisher => ConstructorData.genericCodec(DetailedWeaponData.codec(2), "weapon")
-// case ObjectClass.quadassault_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.r_shotgun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.radiator => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.repeater => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.rocklet => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.rotarychaingun_mosquito => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.scythe => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.skyguard_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.spiker => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.spitfire_aa_weapon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.spitfire_weapon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.striker => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.suppressor => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.thumper => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.thunderer_weapon_systema => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.thunderer_weapon_systemb => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.trhev_burster => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.trhev_dualcycler => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.trhev_pounder => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
-// case ObjectClass.vanguard_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec(2), "weapon")
-// case ObjectClass.vanu_sentry_turret_weapon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.vshev_comet => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.vshev_starfire => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
- case ObjectClass.vshev_quasar => ConstructorData.genericCodec(DetailedWeaponData.codec(-1), "weapon")
-// case ObjectClass.vulture_bomb_bay => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.vulture_nose_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.vulture_tail_cannon => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.wasp_weapon_system => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.beamer => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.cannon_dropship_20mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gun => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.anniversary_guna => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gunb => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_ballgun_l => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_ballgun_r => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systema => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemb => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemc => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemc_nc => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemc_tr => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemc_vs => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemd => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemd_nc => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemd_tr => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.apc_weapon_systemd_vs => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_immolation_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_plasma_rocket_pod => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aurora_weapon_systema => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.aurora_weapon_systemb => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.battlewagon_weapon_systema => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.battlewagon_weapon_systemb => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.battlewagon_weapon_systemc => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.battlewagon_weapon_systemd => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.bolt_driver => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.chainblade => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_cluster_bomb_pod => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_dual_100mm_cannons => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cycler => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.dropship_rear_turret => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.energy_gun => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_nc => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_tr => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_vs => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.flail_weapon => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.flamethrower => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.flechette => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.flux_cannon_thresher => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.fluxpod => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.forceblade => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.fragmentation_grenade => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.fury_weapon_systema => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.galaxy_gunship_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.galaxy_gunship_gun => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.galaxy_gunship_tailgun => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.gauss => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.gauss_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.grenade_launcher_marauder => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.heavy_rail_beam_magrider => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.heavy_sniper => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.hellfire => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.hunterseeker => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.ilc9 => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.isp => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.jammer_grenade => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.katana => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.lancer => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.lasher => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.liberator_25mm_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.liberator_bomb_bay => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.liberator_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.lightgunship_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.lightning_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.maelstrom => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.magcutter => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.mediumtransport_weapon_systemA => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.mediumtransport_weapon_systemB => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.mini_chaingun => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.oicw => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.nchev_falcon => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.nchev_scattercannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.nchev_sparrow => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.particle_beam_magrider => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_rocket_pods => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_particle_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow_left => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow_right => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.phalanx_avcombo => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.phalanx_flakcombo => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.phalanx_sgl_hevgatcan => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.phoenix => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.prowler_weapon_systemA => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.prowler_weapon_systemB => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.plasma_grenade => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.pulsar => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.pulsed_particle_accelerator => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.punisher => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.quadassault_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.r_shotgun => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.radiator => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.repeater => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.rocklet => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.rotarychaingun_mosquito => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.scythe => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.skyguard_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.spiker => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.spitfire_aa_weapon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.spitfire_weapon => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.striker => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.suppressor => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.thumper => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.thunderer_weapon_systema => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.thunderer_weapon_systemb => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.trhev_burster => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.trhev_dualcycler => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.trhev_pounder => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.vanguard_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.vanu_sentry_turret_weapon => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.vshev_comet => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.vshev_starfire => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.vshev_quasar => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.vulture_bomb_bay => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.vulture_nose_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.vulture_tail_cannon => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.wasp_weapon_system => ConstructorData(DetailedWeaponData.codec, "weapon")
//other weapons
- case ObjectClass.ace_deployable => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.advanced_missile_launcher_t => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cannon_20mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cannon_75mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cannon_deliverer_20mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cannon_dropship_l_20mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.chaingun_12mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.chaingun_15mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.chaingun_p => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cycler_v2 => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cycler_v3 => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.cycler_v4 => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.dynomite => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.frag_grenade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.generic_grenade => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.lightning_75mm => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.mine_sweeper => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.pellet_gun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
-// case ObjectClass.phantasm_12mm_machinegun => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.six_shooter => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
- case ObjectClass.winchester => ConstructorData.genericCodec(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.ace_deployable => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.advanced_missile_launcher_t => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cannon_20mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cannon_75mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cannon_deliverer_20mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cannon_dropship_l_20mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.chaingun_12mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.chaingun_15mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.chaingun_p => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cycler_v2 => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cycler_v3 => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.cycler_v4 => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.dynomite => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.frag_grenade => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.generic_grenade => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.lightning_75mm => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.mine_sweeper => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.pellet_gun => ConstructorData(DetailedWeaponData.codec, "weapon")
+// case ObjectClass.phantasm_12mm_machinegun => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.six_shooter => ConstructorData(DetailedWeaponData.codec, "weapon")
+ case ObjectClass.winchester => ConstructorData(DetailedWeaponData.codec, "weapon")
//medkits
- case ObjectClass.medkit => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.super_armorkit => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.super_medkit => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
- case ObjectClass.super_staminakit => ConstructorData.genericCodec(DetailedAmmoBoxData.codec, "ammo box")
+ case ObjectClass.medkit => ConstructorData(DetailedAmmoBoxData.codec, "medkit")
+ case ObjectClass.super_armorkit => ConstructorData(DetailedAmmoBoxData.codec, "repair kit")
+ case ObjectClass.super_medkit => ConstructorData(DetailedAmmoBoxData.codec, "super medkit")
+ case ObjectClass.super_staminakit => ConstructorData(DetailedAmmoBoxData.codec, "stamina kit")
//tools
- case ObjectClass.applicator => ConstructorData.genericCodec(DetailedWeaponData.codec, "tool")
- case ObjectClass.bank => ConstructorData.genericCodec(DetailedWeaponData.codec, "tool")
- case ObjectClass.command_detonater => ConstructorData.genericCodec(DetailedCommandDetonaterData.codec, "tool")
- case ObjectClass.flail_targeting_laser => ConstructorData.genericCodec(DetailedCommandDetonaterData.codec, "tool")
- case ObjectClass.medicalapplicator => ConstructorData.genericCodec(DetailedWeaponData.codec, "tool")
- case ObjectClass.nano_dispenser => ConstructorData.genericCodec(DetailedWeaponData.codec, "tool")
- case ObjectClass.remote_electronics_kit => ConstructorData.genericCodec(DetailedREKData.codec, "tool")
- case ObjectClass.trek => ConstructorData.genericCodec(DetailedWeaponData.codec, "tool")
+ case ObjectClass.applicator => ConstructorData(DetailedWeaponData.codec, "tool")
+ case ObjectClass.bank => ConstructorData(DetailedWeaponData.codec, "tool")
+ case ObjectClass.command_detonater => ConstructorData(DetailedCommandDetonaterData.codec, "tool")
+ case ObjectClass.flail_targeting_laser => ConstructorData(DetailedCommandDetonaterData.codec, "tool")
+ case ObjectClass.medicalapplicator => ConstructorData(DetailedWeaponData.codec, "tool")
+ case ObjectClass.nano_dispenser => ConstructorData(DetailedWeaponData.codec, "tool")
+ case ObjectClass.remote_electronics_kit => ConstructorData(DetailedREKData.codec, "tool")
+ case ObjectClass.trek => ConstructorData(DetailedWeaponData.codec, "tool")
//ace deployable
- case ObjectClass.ace => ConstructorData.genericCodec(DetailedACEData.codec, "ace")
- case ObjectClass.advanced_ace => ConstructorData.genericCodec(DetailedACEData.codec, "advanced ace")
- case ObjectClass.router_telepad => ConstructorData.genericCodec(DetailedTelepadData.codec, "router telepad")
- case ObjectClass.boomer_trigger => ConstructorData.genericCodec(DetailedBoomerTriggerData.codec, "boomer trigger")
+ case ObjectClass.ace => ConstructorData(DetailedConstructionToolData.codec, "ace")
+ case ObjectClass.advanced_ace => ConstructorData(DetailedConstructionToolData.codec, "advanced ace")
+ case ObjectClass.router_telepad => ConstructorData(DetailedConstructionToolData.codec, "router telepad")
+ case ObjectClass.boomer_trigger => ConstructorData(DetailedConstructionToolData.codec, "boomer trigger")
//other
- case ObjectClass.avatar => ConstructorData.genericCodec(DetailedPlayerData.codec(false), "avatar")
- case ObjectClass.locker_container => ConstructorData.genericCodec(DetailedLockerContainerData.codec, "locker container")
+ case ObjectClass.avatar => ConstructorData(DetailedPlayerData.codec(false), "avatar")
+ case ObjectClass.locker_container => ConstructorData(DetailedLockerContainerData.codec, "locker container")
//failure case
case _ => defaultFailureCodec(objClass)
}
- def selectDataDroppedDetailedCodec(objClass : Int) : Codec[ConstructorData.genericPattern] =
+ def selectDataDroppedDetailedCodec(objClass : Int) : Codec[ConstructorData] =
(objClass : @switch) match {
//special cases
- case ObjectClass.avatar => ConstructorData.genericCodec(DetailedPlayerData.codec(true), "avatar")
+ case ObjectClass.avatar => ConstructorData(DetailedPlayerData.codec(true), "avatar")
//defer to other codec selection
case _ => selectDataDetailedCodec(objClass)
}
@@ -690,291 +701,296 @@ object ObjectClass {
* @return the `Codec` that handles the format of data for that particular item class, or a failing `Codec`
* @see `ConstructorData`
*/
- def selectDataCodec(objClass : Int) : Codec[ConstructorData.genericPattern] =
+ def selectDataCodec(objClass : Int) : Codec[ConstructorData] =
(objClass : @switch) match {
//ammunition
- case ObjectClass.bullet_105mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_12mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_150mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_15mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_20mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_25mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_35mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_75mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm_AP => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_combo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_vehicle => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.anniversary_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_immolation_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_laser_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_plasma_rocket_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_ppa_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_starfire_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_canister => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_siphon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bolt => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.burster_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_100mm_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_burster_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_chaingun_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_cluster_bomb_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_tank_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.comet_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.dualcycler_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_cell => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_gun_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.falcon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.firebird_missile => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.flamethrower_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.flux_cannon_thresher_battery => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.fluxpod_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.frag_cartridge => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.frag_grenade_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.gauss_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.grenade => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.health_canister => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_grenade_mortar => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_rail_beam_battery => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.hellfire_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.hunter_seeker_missile => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.jammer_cartridge => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.jammer_grenade_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.lancer_cartridge => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.liberator_bomb => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.maelstrom_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.melee_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.mine => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.mine_sweeper_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ntu_siphon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.oicw_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pellet_gun_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_dual_machine_gun_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_mechhammer_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_particle_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_rocket_pod_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_sparrow_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.phalanx_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.phoenix_missile => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.plasma_cartridge => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.plasma_grenade_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pounder_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pulse_battery => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.quasar_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.reaver_rocket => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.rocket => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.scattercannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell_AP => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.six_shooter_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.skyguard_flak_cannon_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.sparrow_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_aa_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.starfire_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.striker_missile_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.trek_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.upgrade_canister => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_gun_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_rocket_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.winchester_ammo => ConstructorData.genericCodec(AmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_105mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_12mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_150mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_15mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_20mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_25mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_35mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_75mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_9mm => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_9mm_AP => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ancient_ammo_combo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ancient_ammo_vehicle => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.anniversary_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_immolation_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_laser_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_plasma_rocket_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_ppa_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_starfire_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.armor_canister => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.armor_siphon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bolt => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.burster_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_100mm_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_burster_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_chaingun_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_cluster_bomb_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_tank_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.comet_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.dualcycler_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.energy_cell => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.energy_gun_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.falcon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.firebird_missile => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.flamethrower_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.flux_cannon_thresher_battery => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.fluxpod_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.frag_cartridge => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.frag_grenade_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.gauss_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.grenade => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.health_canister => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.heavy_grenade_mortar => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.heavy_rail_beam_battery => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.hellfire_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.hunter_seeker_missile => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.jammer_cartridge => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.jammer_grenade_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.lancer_cartridge => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.liberator_bomb => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.maelstrom_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.melee_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.mine => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.mine_sweeper_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ntu_siphon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.oicw_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pellet_gun_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_dual_machine_gun_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_mechhammer_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_particle_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_rocket_pod_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_sparrow_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.phalanx_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.phoenix_missile => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.plasma_cartridge => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.plasma_grenade_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pounder_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pulse_battery => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.quasar_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.reaver_rocket => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.rocket => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.scattercannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.shotgun_shell => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.shotgun_shell_AP => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.six_shooter_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.skyguard_flak_cannon_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.sparrow_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.spitfire_aa_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.spitfire_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.starfire_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.striker_missile_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.trek_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.upgrade_canister => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.wasp_gun_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.wasp_rocket_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.winchester_ammo => ConstructorData(CommonFieldData.codec2, "ammo box")
//weapons
- case ObjectClass.beamer => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_gun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_guna => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_gunb => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_ballgun_l => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_ballgun_r => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systema => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemb => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemc => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemc_nc => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemc_tr => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemc_vs => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemd => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemd_nc => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemd_tr => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.apc_weapon_systemd_vs => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_immolation_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_laser => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_laser_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_laser_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_plasma_rocket_pod => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_ppa => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_ppa_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_ppa_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_starfire => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_starfire_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aphelion_starfire_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aurora_weapon_systema => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.aurora_weapon_systemb => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.battlewagon_weapon_systema => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.battlewagon_weapon_systemb => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.battlewagon_weapon_systemc => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.battlewagon_weapon_systemd => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.bolt_driver => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chainblade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chaingun_p => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_burster => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_burster_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_burster_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_chaingun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_chaingun_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_chaingun_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_cluster_bomb_pod => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_dual_100mm_cannons => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_tank_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_tank_cannon_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.colossus_tank_cannon_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.dropship_rear_turret => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.energy_gun_nc => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.energy_gun_tr => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.energy_gun_vs => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flail_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flamethrower => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flechette => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flux_cannon_thresher => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.fluxpod => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.forceblade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.fragmentation_grenade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.fury_weapon_systema => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.galaxy_gunship_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.galaxy_gunship_gun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.galaxy_gunship_tailgun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.gauss => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.gauss_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.grenade_launcher_marauder => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.heavy_rail_beam_magrider => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.heavy_sniper => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.hellfire => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.hunterseeker => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.ilc9 => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.isp => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.jammer_grenade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.katana => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.lancer => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.lasher => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.liberator_25mm_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.liberator_bomb_bay => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.liberator_weapon_system => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.lightgunship_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.lightning_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.maelstrom => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.magcutter => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mediumtransport_weapon_systemA => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mediumtransport_weapon_systemB => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mini_chaingun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.nchev_falcon => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.nchev_scattercannon => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.nchev_sparrow => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.oicw => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.particle_beam_magrider => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.pellet_gun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_dual_machine_gun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_dual_machine_gun_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_dual_machine_gun_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_dual_rocket_pods => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_mechhammer => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_mechhammer_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_mechhammer_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_particle_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_sparrow => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_sparrow_left => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.peregrine_sparrow_right => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phalanx_avcombo => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phalanx_flakcombo => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phalanx_sgl_hevgatcan => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phoenix => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.plasma_grenade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.prowler_weapon_systemA => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.prowler_weapon_systemB => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.pulsar => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.pulsed_particle_accelerator => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.punisher => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.quadassault_weapon_system => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.r_shotgun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.radiator => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.repeater => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.rocklet => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.rotarychaingun_mosquito => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.scythe => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.skyguard_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.spiker => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.spitfire_aa_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.spitfire_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.striker => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.suppressor => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.thumper => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.thunderer_weapon_systema => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.thunderer_weapon_systemb => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.trhev_burster => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.trhev_dualcycler => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.trhev_pounder => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.vanguard_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.vanu_sentry_turret_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.vshev_comet => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.vshev_quasar => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.vshev_starfire => ConstructorData.genericCodec(WeaponData.codec(-1), "weapon")
- case ObjectClass.vulture_bomb_bay => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.vulture_nose_weapon_system => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.vulture_tail_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.wasp_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon")
+ case ObjectClass.beamer => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_guna => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gunb => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_ballgun_l => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_ballgun_r => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systema => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemb => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemc => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemc_nc => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemc_tr => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemc_vs => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemd => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemd_nc => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemd_tr => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.apc_weapon_systemd_vs => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_immolation_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_laser => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_laser_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_laser_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_plasma_rocket_pod => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_ppa => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_ppa_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_ppa_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_starfire => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_starfire_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aphelion_starfire_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aurora_weapon_systema => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.aurora_weapon_systemb => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.battlewagon_weapon_systema => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.battlewagon_weapon_systemb => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.battlewagon_weapon_systemc => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.battlewagon_weapon_systemd => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.bolt_driver => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.chainblade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.chaingun_p => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_burster => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_burster_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_burster_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_chaingun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_chaingun_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_chaingun_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_cluster_bomb_pod => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_dual_100mm_cannons => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_tank_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_tank_cannon_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.colossus_tank_cannon_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.dropship_rear_turret => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.energy_gun_nc => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.energy_gun_tr => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.energy_gun_vs => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.flail_weapon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.flamethrower => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.flechette => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.flux_cannon_thresher => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.fluxpod => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.forceblade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.fragmentation_grenade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.fury_weapon_systema => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.galaxy_gunship_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.galaxy_gunship_gun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.galaxy_gunship_tailgun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.gauss => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.gauss_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.grenade_launcher_marauder => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.heavy_rail_beam_magrider => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.heavy_sniper => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.hellfire => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.hunterseeker => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.ilc9 => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.isp => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.jammer_grenade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.katana => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.lancer => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.lasher => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.liberator_25mm_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.liberator_bomb_bay => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.liberator_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.lightgunship_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.lightning_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.maelstrom => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.magcutter => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.mediumtransport_weapon_systemA => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.mediumtransport_weapon_systemB => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.mini_chaingun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.nchev_falcon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.nchev_scattercannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.nchev_sparrow => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.oicw => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.particle_beam_magrider => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.pellet_gun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_dual_machine_gun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_dual_machine_gun_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_dual_machine_gun_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_dual_rocket_pods => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_mechhammer => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_mechhammer_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_mechhammer_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_particle_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_sparrow => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_sparrow_left => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.peregrine_sparrow_right => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.phalanx_avcombo => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.phalanx_flakcombo => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.phalanx_sgl_hevgatcan => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.phoenix => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.plasma_grenade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.prowler_weapon_systemA => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.prowler_weapon_systemB => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.pulsar => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.pulsed_particle_accelerator => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.punisher => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.quadassault_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.r_shotgun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.radiator => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.repeater => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.rocklet => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.rotarychaingun_mosquito => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.scythe => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.skyguard_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.spiker => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.spitfire_aa_weapon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.spitfire_weapon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.striker => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.suppressor => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.thumper => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.thunderer_weapon_systema => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.thunderer_weapon_systemb => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.trhev_burster => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.trhev_dualcycler => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.trhev_pounder => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vanguard_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vanu_sentry_turret_weapon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vshev_comet => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vshev_quasar => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vshev_starfire => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vulture_bomb_bay => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vulture_nose_weapon_system => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.vulture_tail_cannon => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.wasp_weapon_system => ConstructorData(WeaponData.codec, "weapon")
//other weapons
- case ObjectClass.ace_deployable => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.advanced_missile_launcher_t => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cannon_20mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cannon_75mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cannon_deliverer_20mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cannon_dropship_l_20mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cannon_dropship_20mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chaingun_12mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chaingun_15mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v2 => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v3 => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v4 => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.dynomite => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.energy_gun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.frag_grenade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.generic_grenade => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.lightning_75mm => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mine_sweeper => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phantasm_12mm_machinegun => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.six_shooter => ConstructorData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.winchester => ConstructorData.genericCodec(WeaponData.codec, "weapon")
+ case ObjectClass.ace_deployable => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.advanced_missile_launcher_t => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cannon_20mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cannon_75mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cannon_deliverer_20mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cannon_dropship_l_20mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cannon_dropship_20mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.chaingun_12mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.chaingun_15mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v2 => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v3 => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v4 => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.dynomite => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.energy_gun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.frag_grenade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.generic_grenade => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.lightning_75mm => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.mine_sweeper => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.phantasm_12mm_machinegun => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.six_shooter => ConstructorData(WeaponData.codec, "weapon")
+ case ObjectClass.winchester => ConstructorData(WeaponData.codec, "weapon")
+ //medkits
+ case ObjectClass.medkit => ConstructorData(CommonFieldData.codec2, "medkit")
+ case ObjectClass.super_armorkit => ConstructorData(CommonFieldData.codec2, "repair kit")
+ case ObjectClass.super_medkit => ConstructorData(CommonFieldData.codec2, "super medkit")
+ case ObjectClass.super_staminakit => ConstructorData(CommonFieldData.codec2, "stamina kit")
//tools
- case ObjectClass.applicator => ConstructorData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.bank => ConstructorData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.command_detonater => ConstructorData.genericCodec(CommandDetonaterData.codec, "tool")
- case ObjectClass.flail_targeting_laser => ConstructorData.genericCodec(CommandDetonaterData.codec, "tool")
- case ObjectClass.medicalapplicator => ConstructorData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.nano_dispenser => ConstructorData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.remote_electronics_kit => ConstructorData.genericCodec(REKData.codec, "tool")
- case ObjectClass.trek => ConstructorData.genericCodec(WeaponData.codec, "tool")
+ case ObjectClass.applicator => ConstructorData(WeaponData.codec, "tool")
+ case ObjectClass.bank => ConstructorData(WeaponData.codec, "tool")
+ case ObjectClass.command_detonater => ConstructorData(HandheldData.codec, "tool")
+ case ObjectClass.flail_targeting_laser => ConstructorData(HandheldData.codec, "tool")
+ case ObjectClass.medicalapplicator => ConstructorData(WeaponData.codec, "tool")
+ case ObjectClass.nano_dispenser => ConstructorData(WeaponData.codec, "tool")
+ case ObjectClass.remote_electronics_kit => ConstructorData(REKData.codec, "tool")
+ case ObjectClass.trek => ConstructorData(WeaponData.codec, "tool")
//deployables
- case ObjectClass.ace => ConstructorData.genericCodec(ACEData.codec, "ace")
- case ObjectClass.advanced_ace => ConstructorData.genericCodec(ACEData.codec, "advanced ace")
- case ObjectClass.router_telepad => ConstructorData.genericCodec(TelepadData.codec, "router telepad")
- case ObjectClass.router_telepad_deployable => ConstructorData.genericCodec(ContainedTelepadDeployableData.codec, "router telepad")
- case ObjectClass.boomer_trigger => ConstructorData.genericCodec(BoomerTriggerData.codec, "boomer trigger")
+ case ObjectClass.ace => ConstructorData(HandheldData.codec, "ace")
+ case ObjectClass.advanced_ace => ConstructorData(HandheldData.codec, "advanced ace")
+ case ObjectClass.router_telepad => ConstructorData(HandheldData.codec, "router telepad")
+ case ObjectClass.router_telepad_deployable => ConstructorData(TelepadDeployableData.codec, "router telepad")
+ case ObjectClass.boomer_trigger => ConstructorData(HandheldData.codec, "boomer trigger")
//vehicles?
- case ObjectClass.orbital_shuttle => ConstructorData.genericCodec(OrbitalShuttleData.codec, "HART")
+ case ObjectClass.orbital_shuttle => ConstructorData(OrbitalShuttleData.codec, "HART")
//other
- case ObjectClass.ams_order_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.ams_respawn_tube => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.avatar => ConstructorData.genericCodec(PlayerData.codec(false), "avatar")
- case ObjectClass.bfr_rearm_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.implant_terminal_interface => ConstructorData.genericCodec(CommonTerminalData.codec, "implant terminal")
- case ObjectClass.lodestar_repair_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.matrix_terminala => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.matrix_terminalb => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.matrix_terminalc => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.multivehicle_rearm_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminala => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminalb => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.targeting_laser_dispenser => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.teleportpad_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
+ case ObjectClass.ams_order_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.ams_respawn_tube => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.avatar => ConstructorData(PlayerData.codec(false), "avatar")
+ case ObjectClass.bfr_rearm_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.implant_terminal_interface => ConstructorData(CommonFieldData.codec2, "implant terminal")
+ case ObjectClass.lodestar_repair_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.matrix_terminala => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.matrix_terminalb => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.matrix_terminalc => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.multivehicle_rearm_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminala => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminalb => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.targeting_laser_dispenser => ConstructorData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.teleportpad_terminal => ConstructorData(CommonFieldData.codec2, "terminal")
//failure case
case _ => defaultFailureCodec(objClass)
}
@@ -988,307 +1004,316 @@ object ObjectClass {
* @return the `Codec` that handles the format of data for that particular item class, or a failing `Codec`
* @see `ConstructorData`
*/
- def selectDataDroppedCodec(objClass : Int) : Codec[ConstructorData.genericPattern] =
+ def selectDataDroppedCodec(objClass : Int) : Codec[ConstructorData] =
(objClass : @switch) match {
//ammunition
- case ObjectClass.bullet_105mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_12mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_150mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_15mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_20mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_25mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_35mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_75mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bullet_9mm_AP => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_combo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ancient_ammo_vehicle => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.anniversary_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_immolation_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_laser_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_plasma_rocket_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_ppa_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.aphelion_starfire_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_canister => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.armor_siphon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.bolt => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.burster_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_100mm_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_burster_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_chaingun_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_cluster_bomb_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.colossus_tank_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.comet_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.dualcycler_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_cell => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.energy_gun_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.falcon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.firebird_missile => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.flamethrower_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.flux_cannon_thresher_battery => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.fluxpod_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.frag_cartridge => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
-// case ObjectClass.frag_grenade_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.gauss_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.grenade => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.health_canister => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_grenade_mortar => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.heavy_rail_beam_battery => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.hellfire_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.hunter_seeker_missile => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.jammer_cartridge => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
-// case ObjectClass.jammer_grenade_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.lancer_cartridge => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.liberator_bomb => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.maelstrom_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.melee_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.mine => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.mine_sweeper_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.ntu_siphon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.oicw_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pellet_gun_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_dual_machine_gun_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_mechhammer_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_particle_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_rocket_pod_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.peregrine_sparrow_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.phalanx_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.phoenix_missile => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.plasma_cartridge => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
-// case ObjectClass.plasma_grenade_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pounder_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.pulse_battery => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.quasar_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.reaver_rocket => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.rocket => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.scattercannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.shotgun_shell_AP => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.six_shooter_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.skyguard_flak_cannon_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.sparrow_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_aa_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.spitfire_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.starfire_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.striker_missile_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
-// case ObjectClass.trek_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.upgrade_canister => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_gun_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.wasp_rocket_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
- case ObjectClass.winchester_ammo => DroppedItemData.genericCodec(AmmoBoxData.codec, "ammo box")
+ case ObjectClass.bullet_105mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_12mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_150mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_15mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_20mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_25mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_35mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_75mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_9mm => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bullet_9mm_AP => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ancient_ammo_combo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ancient_ammo_vehicle => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.anniversary_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_immolation_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_laser_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_plasma_rocket_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_ppa_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.aphelion_starfire_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.armor_canister => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.armor_siphon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.bolt => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.burster_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_100mm_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_burster_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_chaingun_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_cluster_bomb_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.colossus_tank_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.comet_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.dualcycler_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.energy_cell => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.energy_gun_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.falcon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.firebird_missile => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.flamethrower_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.flux_cannon_thresher_battery => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.fluxpod_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.frag_cartridge => DroppedItemData(CommonFieldData.codec2, "ammo box")
+// case ObjectClass.frag_grenade_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.gauss_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.grenade => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.health_canister => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.heavy_grenade_mortar => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.heavy_rail_beam_battery => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.hellfire_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.hunter_seeker_missile => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.jammer_cartridge => DroppedItemData(CommonFieldData.codec2, "ammo box")
+// case ObjectClass.jammer_grenade_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.lancer_cartridge => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.liberator_bomb => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.maelstrom_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.melee_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.mine => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.mine_sweeper_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.ntu_siphon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.oicw_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pellet_gun_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_dual_machine_gun_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_mechhammer_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_particle_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_rocket_pod_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.peregrine_sparrow_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.phalanx_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.phoenix_missile => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.plasma_cartridge => DroppedItemData(CommonFieldData.codec2, "ammo box")
+// case ObjectClass.plasma_grenade_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pounder_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.pulse_battery => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.quasar_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.reaver_rocket => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.rocket => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.scattercannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.shotgun_shell => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.shotgun_shell_AP => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.six_shooter_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.skyguard_flak_cannon_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.sparrow_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.spitfire_aa_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.spitfire_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.starfire_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.striker_missile_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+// case ObjectClass.trek_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.upgrade_canister => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.wasp_gun_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.wasp_rocket_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
+ case ObjectClass.winchester_ammo => DroppedItemData(CommonFieldData.codec2, "ammo box")
//weapons
- case ObjectClass.beamer => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_gun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_guna => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.anniversary_gunb => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_immolation_cannon => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_laser_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_plasma_rocket_pod => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_ppa_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.aphelion_starfire_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.bolt_driver => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chainblade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.chaingun_p => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_burster_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_chaingun_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_cluster_bomb_pod => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_dual_100mm_cannons => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.colossus_tank_cannon_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.energy_gun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_nc => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_tr => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.energy_gun_vs => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flamethrower => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.flechette => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.forceblade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.fragmentation_grenade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.gauss => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.heavy_sniper => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.hellfire => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.hunterseeker => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.ilc9 => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.isp => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.jammer_grenade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.katana => DroppedItemData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.lancer => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.lasher => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.maelstrom => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.magcutter => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mini_chaingun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.oicw => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_machine_gun_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_dual_rocket_pods => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_mechhammer_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_particle_cannon => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow_left => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.peregrine_sparrow_right => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.phoenix => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.pulsar => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.plasma_grenade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.punisher => DroppedItemData.genericCodec(WeaponData.codec(2), "weapon")
- case ObjectClass.r_shotgun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.radiator => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.repeater => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.rocklet => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.spiker => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.spitfire_aa_weapon => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
-// case ObjectClass.spitfire_weapon => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.striker => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.suppressor => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.thumper => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
+ case ObjectClass.beamer => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gun => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_guna => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.anniversary_gunb => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_immolation_cannon => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_laser_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_plasma_rocket_pod => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_ppa_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.aphelion_starfire_right => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.bolt_driver => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.chainblade => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.chaingun_p => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_burster_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_chaingun_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_cluster_bomb_pod => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_dual_100mm_cannons => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.colossus_tank_cannon_right => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.energy_gun => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_nc => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_tr => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.energy_gun_vs => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.flamethrower => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.flechette => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.forceblade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.fragmentation_grenade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.gauss => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.heavy_sniper => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.hellfire => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.hunterseeker => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.ilc9 => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.isp => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.jammer_grenade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.katana => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.lancer => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.lasher => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.maelstrom => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.magcutter => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.mini_chaingun => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.oicw => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_machine_gun_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_dual_rocket_pods => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_mechhammer_right => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_particle_cannon => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow_left => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.peregrine_sparrow_right => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.phoenix => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.pulsar => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.plasma_grenade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.punisher => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.r_shotgun => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.radiator => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.repeater => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.rocklet => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.spiker => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.spitfire_aa_weapon => DroppedItemData(WeaponData.codec, "weapon")
+// case ObjectClass.spitfire_weapon => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.striker => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.suppressor => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.thumper => DroppedItemData(WeaponData.codec, "weapon")
//other weapons
- case ObjectClass.ace_deployable => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.advanced_missile_launcher_t => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chaingun_12mm => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.chaingun_15mm => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v2 => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v3 => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.cycler_v4 => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.dynomite => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.frag_grenade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.generic_grenade => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.mine_sweeper => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.pellet_gun => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.six_shooter => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
- case ObjectClass.winchester => DroppedItemData.genericCodec(WeaponData.codec, "weapon")
+ case ObjectClass.ace_deployable => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.advanced_missile_launcher_t => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.chaingun_12mm => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.chaingun_15mm => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v2 => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v3 => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.cycler_v4 => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.dynomite => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.frag_grenade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.generic_grenade => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.mine_sweeper => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.pellet_gun => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.six_shooter => DroppedItemData(WeaponData.codec, "weapon")
+ case ObjectClass.winchester => DroppedItemData(WeaponData.codec, "weapon")
//medkits
- case ObjectClass.medkit => DroppedItemData.genericCodec(AmmoBoxData.codec, "medkit")
- case ObjectClass.super_armorkit => DroppedItemData.genericCodec(AmmoBoxData.codec, "repair kit")
- case ObjectClass.super_medkit => DroppedItemData.genericCodec(AmmoBoxData.codec, "medkit")
- case ObjectClass.super_staminakit => DroppedItemData.genericCodec(AmmoBoxData.codec, "stamina kit")
+ case ObjectClass.medkit => DroppedItemData(CommonFieldData.codec2, "medkit")
+ case ObjectClass.super_armorkit => DroppedItemData(CommonFieldData.codec2, "repair kit")
+ case ObjectClass.super_medkit => DroppedItemData(CommonFieldData.codec2, "super medkit")
+ case ObjectClass.super_staminakit => DroppedItemData(CommonFieldData.codec2, "stamina kit")
//tools
- case ObjectClass.applicator => DroppedItemData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.bank => DroppedItemData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.command_detonater => DroppedItemData.genericCodec(CommandDetonaterData.codec, "tool")
- case ObjectClass.flail_targeting_laser => DroppedItemData.genericCodec(CommandDetonaterData.codec, "tool")
- case ObjectClass.medicalapplicator => DroppedItemData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.nano_dispenser => DroppedItemData.genericCodec(WeaponData.codec, "tool")
- case ObjectClass.remote_electronics_kit => DroppedItemData.genericCodec(REKData.codec, " tool")
- case ObjectClass.trek => DroppedItemData.genericCodec(WeaponData.codec, "tool")
+ case ObjectClass.applicator => DroppedItemData(WeaponData.codec, "tool")
+ case ObjectClass.bank => DroppedItemData(WeaponData.codec, "tool")
+ case ObjectClass.command_detonater => DroppedItemData(HandheldData.codec, "tool")
+ case ObjectClass.flail_targeting_laser => DroppedItemData(HandheldData.codec, "tool")
+ case ObjectClass.medicalapplicator => DroppedItemData(WeaponData.codec, "tool")
+ case ObjectClass.nano_dispenser => DroppedItemData(WeaponData.codec, "tool")
+ case ObjectClass.remote_electronics_kit => DroppedItemData(REKData.codec, " tool")
+ case ObjectClass.trek => DroppedItemData(WeaponData.codec, "tool")
//deployables
- case ObjectClass.ace => DroppedItemData.genericCodec(ACEData.codec, "ace")
- case ObjectClass.advanced_ace => DroppedItemData.genericCodec(ACEData.codec, "advanced ace")
- case ObjectClass.router_telepad => DroppedItemData.genericCodec(TelepadData.codec, "router telepad") //TODO not correct
- case ObjectClass.boomer_trigger => DroppedItemData.genericCodec(BoomerTriggerData.codec, "boomer trigger")
- case ObjectClass.boomer => ConstructorData.genericCodec(SmallDeployableData.codec, "ace deployable")
- case ObjectClass.he_mine => ConstructorData.genericCodec(SmallDeployableData.codec, "ace deployable")
- case ObjectClass.jammer_mine => ConstructorData.genericCodec(SmallDeployableData.codec, "ace deployable")
- case ObjectClass.motionalarmsensor => ConstructorData.genericCodec(SmallDeployableData.codec, "ace deployable")
- case ObjectClass.sensor_shield => ConstructorData.genericCodec(SmallDeployableData.codec, "ace deployable")
- case ObjectClass.spitfire_aa => ConstructorData.genericCodec(SmallTurretData.codec, "small turret")
- case ObjectClass.spitfire_cloaked => ConstructorData.genericCodec(SmallTurretData.codec, "small turret")
- case ObjectClass.spitfire_turret => ConstructorData.genericCodec(SmallTurretData.codec, "small turret")
- case ObjectClass.tank_traps => ConstructorData.genericCodec(TRAPData.codec, "trap")
- case ObjectClass.deployable_shield_generator => ConstructorData.genericCodec(AegisShieldGeneratorData.codec, "shield generator")
- case ObjectClass.portable_manned_turret => ConstructorData.genericCodec(OneMannedFieldTurretData.codec, "field turret")
- case ObjectClass.portable_manned_turret_nc => ConstructorData.genericCodec(OneMannedFieldTurretData.codec, "field turret")
- case ObjectClass.portable_manned_turret_tr => ConstructorData.genericCodec(OneMannedFieldTurretData.codec, "field turret")
- case ObjectClass.portable_manned_turret_vs => ConstructorData.genericCodec(OneMannedFieldTurretData.codec, "field turret")
- case ObjectClass.router_telepad_deployable => ConstructorData.genericCodec(TelepadDeployableData.codec, "telepad deployable")
+ case ObjectClass.ace => DroppedItemData(HandheldData.codec, "ace")
+ case ObjectClass.advanced_ace => DroppedItemData(HandheldData.codec, "advanced ace")
+ case ObjectClass.router_telepad => DroppedItemData(HandheldData.codec, "router telepad")
+ case ObjectClass.boomer_trigger => DroppedItemData(HandheldData.codec, "boomer trigger")
+ case ObjectClass.boomer => ConstructorData(CommonFieldDataWithPlacement.codec2, "ace deployable")
+ case ObjectClass.he_mine => ConstructorData(CommonFieldDataWithPlacement.codec2, "ace deployable")
+ case ObjectClass.jammer_mine => ConstructorData(CommonFieldDataWithPlacement.codec2, "ace deployable")
+ case ObjectClass.motionalarmsensor => ConstructorData(CommonFieldDataWithPlacement.codec2, "ace deployable")
+ case ObjectClass.sensor_shield => ConstructorData(CommonFieldDataWithPlacement.codec2, "ace deployable")
+ case ObjectClass.spitfire_aa => ConstructorData(SmallTurretData.codec, "small turret")
+ case ObjectClass.spitfire_cloaked => ConstructorData(SmallTurretData.codec, "small turret")
+ case ObjectClass.spitfire_turret => ConstructorData(SmallTurretData.codec, "small turret")
+ case ObjectClass.tank_traps => ConstructorData(TRAPData.codec, "trap")
+ case ObjectClass.deployable_shield_generator => ConstructorData(AegisShieldGeneratorData.codec, "shield generator")
+ case ObjectClass.portable_manned_turret => ConstructorData(OneMannedFieldTurretData.codec, "field turret")
+ case ObjectClass.portable_manned_turret_nc => ConstructorData(OneMannedFieldTurretData.codec, "field turret")
+ case ObjectClass.portable_manned_turret_tr => ConstructorData(OneMannedFieldTurretData.codec, "field turret")
+ case ObjectClass.portable_manned_turret_vs => ConstructorData(OneMannedFieldTurretData.codec, "field turret")
+ case ObjectClass.router_telepad_deployable => DroppedItemData(TelepadDeployableData.codec, "telepad deployable")
//projectiles
- case ObjectClass.hunter_seeker_missile_projectile => ConstructorData.genericCodec(TrackedProjectileData.codec, "projectile")
- case ObjectClass.oicw_projectile => ConstructorData.genericCodec(TrackedProjectileData.codec, "projectile")
- case ObjectClass.starfire_projectile => ConstructorData.genericCodec(TrackedProjectileData.codec, "projectile")
- case ObjectClass.striker_missile_targeting_projectile => ConstructorData.genericCodec(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.hunter_seeker_missile_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.meteor_common => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_b_large => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_b_medium => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_b_small => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_large => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_medium => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.meteor_projectile_small => ConstructorData(TrackedProjectileData.codec, "meteor")
+ case ObjectClass.oicw_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.sparrow_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.starfire_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.striker_missile_targeting_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
+ case ObjectClass.wasp_rocket_projectile => ConstructorData(TrackedProjectileData.codec, "projectile")
//vehicles
- case ObjectClass.ams => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Utility), "ams")
- case ObjectClass.ams_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.ant => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Utility), "ant")
- case ObjectClass.ant_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.apc_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.apc_nc => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.apc_tr => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.apc_vs => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
+ case ObjectClass.ams => ConstructorData(VehicleData.codec(VehicleFormat.Utility), "ams")
+ case ObjectClass.ams_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.ant => ConstructorData(VehicleData.codec(VehicleFormat.Utility), "ant")
+ case ObjectClass.ant_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.apc_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.apc_nc => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.apc_tr => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.apc_vs => ConstructorData(VehicleData.codec, "vehicle")
//case ObjectClass.aphelion_destroyed => normal @ 0 health
- case ObjectClass.aphelion_flight => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.aphelion_gunner => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.aurora => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.battlewagon => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
+ case ObjectClass.aphelion_flight => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.aphelion_gunner => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.aurora => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.battlewagon => ConstructorData(VehicleData.codec, "vehicle")
//case ObjectClass.colossus_destroyed => normal @ 0 health
- case ObjectClass.colossus_flight => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.colossus_gunner => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.droppod => ConstructorData.genericCodec(DroppodData.codec, "droppod")
- case ObjectClass.dropship => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.dropship_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.flail => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.flail_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.fury => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.galaxy_gunship => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.liberator => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.liberator_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.lightgunship => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.lightgunship_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.lightning => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.lightning_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.lodestar => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.lodestar_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.magrider => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.magrider_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.mediumtransport => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.mediumtransport_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.mosquito => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.mosquito_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.orbital_shuttle => ConstructorData.genericCodec(OrbitalShuttleData.codec_pos, "HART")
+ case ObjectClass.colossus_flight => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.colossus_gunner => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.droppod => ConstructorData(DroppodData.codec, "droppod")
+ case ObjectClass.dropship => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.dropship_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.flail => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.flail_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.fury => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.galaxy_gunship => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.liberator => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.liberator_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.lightgunship => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.lightgunship_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.lightning => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.lightning_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.lodestar => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.lodestar_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.magrider => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.magrider_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.mediumtransport => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.mediumtransport_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.mosquito => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.mosquito_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.orbital_shuttle => ConstructorData(OrbitalShuttleData.codec_pos, "HART")
//case ObjectClass.peregrine_destroyed => normal @ 0 health
- case ObjectClass.peregrine_flight => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.peregrine_gunner => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
- case ObjectClass.phantasm => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.peregrine_flight => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.peregrine_gunner => ConstructorData(VehicleData.codec(VehicleFormat.Battleframe), "vehicle")
+ case ObjectClass.phantasm => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
//case ObjectClass.phantasm_destroyed => normal @ 0 health
- case ObjectClass.prowler => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.prowler_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.quadassault => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.quadassault_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.quadstealth => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.quadstealth_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.router => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.router_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.skyguard => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.skyguard_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.switchblade => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.switchblade_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.threemanheavybuggy => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.threemanheavybuggy_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.thunderer => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.two_man_assault_buggy => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.two_man_assault_buggy_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.twomanheavybuggy => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.twomanheavybuggy_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.twomanhoverbuggy => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.twomanhoverbuggy_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.vanguard => ConstructorData.genericCodec(VehicleData.codec, "vehicle")
- case ObjectClass.vanguard_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage")
- case ObjectClass.vulture => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
- case ObjectClass.wasp => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.prowler => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.prowler_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.quadassault => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.quadassault_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.quadstealth => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.quadstealth_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.router => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.router_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.skyguard => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.skyguard_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.switchblade => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.switchblade_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.threemanheavybuggy => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.threemanheavybuggy_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.thunderer => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.two_man_assault_buggy => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.two_man_assault_buggy_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.twomanheavybuggy => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.twomanheavybuggy_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.twomanhoverbuggy => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.twomanhoverbuggy_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.vanguard => ConstructorData(VehicleData.codec, "vehicle")
+ case ObjectClass.vanguard_destroyed => ConstructorData(DestroyedVehicleData.codec, "wreckage")
+ case ObjectClass.vulture => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
+ case ObjectClass.wasp => ConstructorData(VehicleData.codec(VehicleFormat.Variant), "vehicle")
//other
- case ObjectClass.ams_respawn_tube => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.avatar => ConstructorData.genericCodec(PlayerData.codec(true), "avatar")
- case ObjectClass.capture_flag => ConstructorData.genericCodec(CaptureFlagData.codec, "capture flag")
- case ObjectClass.implant_terminal_interface => ConstructorData.genericCodec(CommonTerminalData.codec, "implant terminal")
- case ObjectClass.locker_container => ConstructorData.genericCodec(LockerContainerData.codec, "locker container")
- case ObjectClass.matrix_terminala => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.matrix_terminalb => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.matrix_terminalc => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminal => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminala => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
- case ObjectClass.order_terminalb => DroppedItemData.genericCodec(CommonTerminalData.codec, "terminal")
+ case ObjectClass.ams_respawn_tube => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.avatar => ConstructorData(PlayerData.codec(true), "avatar")
+ case ObjectClass.capture_flag => ConstructorData(CaptureFlagData.codec, "capture flag")
+ case ObjectClass.implant_terminal_interface => ConstructorData(CommonFieldData.codec2, "implant terminal")
+ case ObjectClass.locker_container => ConstructorData(LockerContainerData.codec, "locker container")
+ case ObjectClass.matrix_terminala => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.matrix_terminalb => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.matrix_terminalc => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminal => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminala => DroppedItemData(CommonFieldData.codec2, "terminal")
+ case ObjectClass.order_terminalb => DroppedItemData(CommonFieldData.codec2, "terminal")
//failure case
case _ => defaultFailureCodec(objClass)
}
@@ -1298,16 +1323,10 @@ object ObjectClass {
* @param cls the object class whose `Codec` we have failed to find;
* @return a failure
*/
- private def defaultFailureCodec(cls : Int) : Codec[ConstructorData.genericPattern] = {
- conditional(cls == 0, bool).exmap[ConstructorData.genericPattern] (
- {
- case None | _ =>
- Attempt.failure(Err(s"decoding unknown object class $cls"))
- },
- {
- case None | _ =>
- Attempt.failure(Err(s"encoding unknown object class $cls"))
- }
+ private def defaultFailureCodec(cls : Int) : Codec[ConstructorData] = {
+ conditional(cls == 0, bool).exmap[ConstructorData] (
+ _ => Attempt.failure(Err(s"decoding unknown object class $cls")),
+ _ => Attempt.failure(Err(s"encoding unknown object class $cls"))
)
}
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectCreateBase.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectCreateBase.scala
index 71b77fa8..c66ea269 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectCreateBase.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectCreateBase.scala
@@ -84,22 +84,22 @@ object ObjectCreateBase {
* @return the optional constructed object
* @see `ObjectClass`
*/
- def decodeData(objectClass : Int, data : BitVector, getCodecFunc : (Int) => Codec[ConstructorData.genericPattern]) : Option[ConstructorData] = {
- var out : Option[ConstructorData] = None
+ def decodeData(objectClass : Int, data : BitVector, getCodecFunc : Int => Codec[ConstructorData]) : Attempt[ConstructorData] = {
try {
getCodecFunc(objectClass).decode(data) match {
case Attempt.Successful(decode) =>
- out = decode.value.asInstanceOf[ConstructorData.genericPattern]
- case Attempt.Failure(err) =>
+ Attempt.Successful(decode.value)
+ case result @ Attempt.Failure(err) =>
log.error(s"an object $objectClass failed to decode - ${err.toString}")
log.debug(s"object type: $objectClass, input: ${data.toString}, problem: ${err.toString}")
+ result
}
}
catch {
case ex : Exception =>
- log.error(s"${ex.getClass.toString} - ${ex.toString} ($objectClass)")
+ log.error(s"Decoding error - ${ex.getClass.toString} - ${ex.toString} ($objectClass)")
+ Attempt.failure(Err(ex.getMessage))
}
- out
}
/**
@@ -112,22 +112,23 @@ object ObjectCreateBase {
* @return the bitstream data
* @see `ObjectClass`
*/
- def encodeData(objectClass : Int, obj : ConstructorData, getCodecFunc : (Int) => Codec[ConstructorData.genericPattern]) : BitVector = {
- var out = BitVector.empty
+ def encodeData(objectClass : Int, obj : ConstructorData, getCodecFunc : Int => Codec[ConstructorData]) : Attempt[BitVector] = {
try {
- getCodecFunc(objectClass).encode(Some(obj.asInstanceOf[ConstructorData])) match {
- case Attempt.Successful(encode) =>
- out = encode
- case Attempt.Failure(err) =>
+ getCodecFunc(objectClass).encode(obj.asInstanceOf[ConstructorData]) match {
+ case result @ Attempt.Successful(encode) =>
+ result
+ case result @ Attempt.Failure(err) =>
log.error(s"an $objectClass object failed to encode - ${err.toString}")
log.debug(s"object type: $objectClass, input: ${obj.toString}, problem: ${err.toString}")
+ result
+
}
}
catch {
case ex : Exception =>
- log.error(s"${ex.getClass.toString} - ${ex.toString} ($objectClass)")
+ log.error(s"Encoding error - ${ex.getClass.toString} - ${ex.toString} ($objectClass)")
+ Attempt.failure(Err(ex.getMessage))
}
- out
}
/**
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/OneMannedFieldTurretData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/OneMannedFieldTurretData.scala
index 4b9c1586..9ef570bd 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/OneMannedFieldTurretData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/OneMannedFieldTurretData.scala
@@ -21,7 +21,7 @@ import shapeless.{::, HNil}
* @param health the amount of health the object has, as a percentage of a filled bar
* @param internals data regarding the mountable weapon
*/
-final case class OneMannedFieldTurretData(deploy : SmallDeployableData,
+final case class OneMannedFieldTurretData(deploy : CommonFieldDataWithPlacement,
health : Int,
internals : Option[InventoryData] = None
) extends ConstructorData {
@@ -45,89 +45,89 @@ object OneMannedFieldTurretData extends Marshallable[OneMannedFieldTurretData] {
* @param internals data regarding the mountable weapon
* @return a `OneMannedFieldTurretData` object
*/
- def apply(deploy : SmallDeployableData, health : Int, internals : InventoryData) : OneMannedFieldTurretData =
+ def apply(deploy : CommonFieldDataWithPlacement, health : Int, internals : InventoryData) : OneMannedFieldTurretData =
new OneMannedFieldTurretData(deploy, health, Some(internals))
- /**
- * Prefabricated weapon data for a weaponless field turret mount (`portable_manned_turret`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- *
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def generic(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.energy_gun, wep_guid, 1,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
-
- /**
- * Prefabricated weapon data for the Terran Republic field turret, the Avenger (`portable_manned_turret_tr`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- *
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def avenger(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.energy_gun_tr, wep_guid, 1,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
-
- /**
- * Prefabricated weapon data for the New Conglomerate field turret, the Osprey (`portable_manned_turret_vnc`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def osprey(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.energy_gun_nc, wep_guid, 1,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
-
- /**
- * Prefabricated weapon data for the Vanu Soveriegnty field turret, the Orion (`portable_manned_turret_vs`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def orion(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.energy_gun_vs, wep_guid, 1,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
+// /**
+// * Prefabricated weapon data for a weaponless field turret mount (`portable_manned_turret`).
+// * @param wep_guid the uid to assign to the weapon
+// * @param wep_unk1 na;
+// * used by `WeaponData`
+// *
+// * @param wep_unk2 na;
+// * used by `WeaponData`
+// * @param ammo_guid the uid to assign to the ammo
+// * @param ammo_unk na;
+// * used by `AmmoBoxData`
+// * @return an `InternalSlot` object
+// */
+// def generic(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
+// InternalSlot(ObjectClass.energy_gun, wep_guid, 1,
+// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
+// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
+// )
+// )
+//
+// /**
+// * Prefabricated weapon data for the Terran Republic field turret, the Avenger (`portable_manned_turret_tr`).
+// * @param wep_guid the uid to assign to the weapon
+// * @param wep_unk1 na;
+// * used by `WeaponData`
+// *
+// * @param wep_unk2 na;
+// * used by `WeaponData`
+// * @param ammo_guid the uid to assign to the ammo
+// * @param ammo_unk na;
+// * used by `AmmoBoxData`
+// * @return an `InternalSlot` object
+// */
+// def avenger(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
+// InternalSlot(ObjectClass.energy_gun_tr, wep_guid, 1,
+// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
+// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
+// )
+// )
+//
+// /**
+// * Prefabricated weapon data for the New Conglomerate field turret, the Osprey (`portable_manned_turret_vnc`).
+// * @param wep_guid the uid to assign to the weapon
+// * @param wep_unk1 na;
+// * used by `WeaponData`
+// * @param wep_unk2 na;
+// * used by `WeaponData`
+// * @param ammo_guid the uid to assign to the ammo
+// * @param ammo_unk na;
+// * used by `AmmoBoxData`
+// * @return an `InternalSlot` object
+// */
+// def osprey(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
+// InternalSlot(ObjectClass.energy_gun_nc, wep_guid, 1,
+// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
+// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
+// )
+// )
+//
+// /**
+// * Prefabricated weapon data for the Vanu Soveriegnty field turret, the Orion (`portable_manned_turret_vs`).
+// * @param wep_guid the uid to assign to the weapon
+// * @param wep_unk1 na;
+// * used by `WeaponData`
+// * @param wep_unk2 na;
+// * used by `WeaponData`
+// * @param ammo_guid the uid to assign to the ammo
+// * @param ammo_unk na;
+// * used by `AmmoBoxData`
+// * @return an `InternalSlot` object
+// */
+// def orion(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
+// InternalSlot(ObjectClass.energy_gun_vs, wep_guid, 1,
+// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
+// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
+// )
+// )
implicit val codec : Codec[OneMannedFieldTurretData] = (
- ("deploy" | SmallDeployableData.codec) ::
+ ("deploy" | CommonFieldDataWithPlacement.codec2) ::
PlanetSideGUID.codec :: //hoist/extract with the deploy.owner_guid in field above
bool ::
("health" | uint8L) ::
@@ -144,30 +144,35 @@ object OneMannedFieldTurretData extends Marshallable[OneMannedFieldTurretData] {
else {
(health, internals)
}
+ val data = deploy.data
Attempt.successful(
OneMannedFieldTurretData(
- SmallDeployableData(deploy.pos, deploy.faction, deploy.bops, deploy.destroyed, deploy.unk1, deploy.jammered, deploy.unk2, player),
+ CommonFieldDataWithPlacement(
+ deploy.pos,
+ CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.v3, data.v4, data.v5, player)
+ ),
newHealth,
newInternals
)
)
- case _ =>
- Attempt.failure(Err("invalid omft data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid field turret data format - $data"))
},
{
- case OneMannedFieldTurretData(deploy, health, internals) =>
+ case OneMannedFieldTurretData(CommonFieldDataWithPlacement(pos, data), health, internals) =>
val (newHealth, newInternals) = if(health == 0 || internals.isEmpty || internals.get.contents.isEmpty) {
(0, None)
}
else {
(health, internals)
}
- val newDeploy = SmallDeployableData(deploy.pos, deploy.faction, deploy.bops, deploy.destroyed, deploy.unk1, deploy.jammered, deploy.unk2, PlanetSideGUID(0))
- Attempt.successful(newDeploy :: deploy.owner_guid :: false :: newHealth :: 0 :: 0xF :: 0 :: newInternals :: HNil)
-
- case _ =>
- Attempt.failure(Err("invalid omft data format"))
+ Attempt.successful(
+ CommonFieldDataWithPlacement(
+ pos,
+ CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.v3, data.v4, data.v5, PlanetSideGUID(0))
+ ) :: data.guid :: false :: newHealth :: 0 :: 0xF :: 0 :: newInternals :: HNil
+ )
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/OrbitalShuttleData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/OrbitalShuttleData.scala
index 017a8055..a9b79e21 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/OrbitalShuttleData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/OrbitalShuttleData.scala
@@ -66,6 +66,9 @@ object OrbitalShuttleData extends Marshallable[OrbitalShuttleData] {
{
case faction :: 0 :: 255 :: 0 :: 7 :: 0 :: HNil =>
Attempt.successful(OrbitalShuttleData(faction))
+
+ case data =>
+ Attempt.failure(Err(s"invalid shuttle data format - $data"))
},
{
case OrbitalShuttleData(faction, _) =>
@@ -90,8 +93,8 @@ object OrbitalShuttleData extends Marshallable[OrbitalShuttleData] {
case pos :: faction :: 0 :: 255 :: 0 :: 255 :: 0 :: 15 :: false :: HNil =>
Attempt.successful(OrbitalShuttleData(faction, Some(pos)))
- case _ =>
- Attempt.failure(Err("invalid shuttle data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid shuttle data format - $data"))
},
{
case OrbitalShuttleData(faction, Some(pos)) =>
@@ -99,9 +102,6 @@ object OrbitalShuttleData extends Marshallable[OrbitalShuttleData] {
case OrbitalShuttleData(_, None) =>
Attempt.failure(Err("invalid shuttle data format (needs position)"))
-
- case _ =>
- Attempt.failure(Err("invalid shuttle data format"))
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/PlayerData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/PlayerData.scala
index 12b398d8..84613ad4 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/PlayerData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/PlayerData.scala
@@ -63,9 +63,9 @@ object PlayerData extends Marshallable[PlayerData] {
* technically, always `DrawnSlot.None`, but the field is preserved to maintain similarity
* @return a `PlayerData` object
*/
- def apply(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type) : PlayerData = {
+ def apply(basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type) : PlayerData = {
val appearance = basic_appearance(5)
- PlayerData(None, appearance, character_data(appearance.a.altModel, true), Some(inventory), drawn_slot)(false)
+ PlayerData(None, appearance, character_data(appearance.altModelBit.isDefined, true), Some(inventory), drawn_slot)(false)
}
/**
* Overloaded constructor that ignores the coordinate information and the inventory.
@@ -77,9 +77,9 @@ object PlayerData extends Marshallable[PlayerData] {
* technically, always `DrawnSlot.None`, but the field is preserved to maintain similarity
* @return a `PlayerData` object
*/
- def apply(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type) : PlayerData = {
+ def apply(basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type) : PlayerData = {
val appearance = basic_appearance(5)
- PlayerData(None, appearance, character_data(appearance.a.altModel, true), None, drawn_slot)(false)
+ PlayerData(None, appearance, character_data(appearance.altModelBit.isDefined, true), None, drawn_slot)(false)
}
/**
@@ -93,9 +93,9 @@ object PlayerData extends Marshallable[PlayerData] {
* @param drawn_slot the holster that is initially drawn
* @return a `PlayerData` object
*/
- def apply(pos : PlacementData, basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type) : PlayerData = {
+ def apply(pos : PlacementData, basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type) : PlayerData = {
val appearance = basic_appearance( PaddingOffset(Some(pos)) )
- PlayerData(Some(pos), appearance, character_data(appearance.a.altModel, false), Some(inventory), drawn_slot)(true)
+ PlayerData(Some(pos), appearance, character_data(appearance.altModelBit.isDefined, false), Some(inventory), drawn_slot)(true)
}
/**
* Overloaded constructor that includes the coordinate information but ignores the inventory.
@@ -107,9 +107,9 @@ object PlayerData extends Marshallable[PlayerData] {
* @param drawn_slot the holster that is initially drawn
* @return a `PlayerData` object
*/
- def apply(pos : PlacementData, basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type) : PlayerData = {
+ def apply(pos : PlacementData, basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type) : PlayerData = {
val appearance = basic_appearance( PaddingOffset(Some(pos)) )
- PlayerData(Some(pos), appearance, character_data(appearance.a.altModel, false), None, drawn_slot)(true)
+ PlayerData(Some(pos), appearance, character_data(appearance.altModelBit.isDefined, false), None, drawn_slot)(true)
}
/**
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala
index a767591d..85eb1303 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala
@@ -13,448 +13,448 @@ import net.psforever.types.{DriveState, PlanetSideEmpire}
object Prefab {
object Vehicle {
def ams(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, driveState : DriveState.Value, matrix_guid : PlanetSideGUID, respawn_guid : PlanetSideGUID, term_a_guid : PlanetSideGUID, term_b_guid : PlanetSideGUID) : VehicleData = {
- VehicleData(CommonFieldData(loc, faction, 0), health, driveState, false, UtilityVehicleData(0),
+ VehicleData(loc, CommonFieldData(faction, 0), health, driveState, false, UtilityVehicleData(0),
Some(InventoryData(List(
- InternalSlot(ObjectClass.matrix_terminalc, matrix_guid, 1, CommonTerminalData(faction)),
- InternalSlot(ObjectClass.ams_respawn_tube, respawn_guid, 2, CommonTerminalData(faction)),
- InternalSlot(ObjectClass.order_terminala, term_a_guid, 3, CommonTerminalData(faction)),
- InternalSlot(ObjectClass.order_terminalb, term_b_guid, 4, CommonTerminalData(faction))
+ InternalSlot(ObjectClass.matrix_terminalc, matrix_guid, 1, CommonFieldData(faction)(false)),
+ InternalSlot(ObjectClass.ams_respawn_tube, respawn_guid, 2, CommonFieldData(faction)(false)),
+ InternalSlot(ObjectClass.order_terminala, term_a_guid, 3, CommonFieldData(faction)(false)),
+ InternalSlot(ObjectClass.order_terminalb, term_b_guid, 4, CommonFieldData(faction)(false))
)))
)
}
def ant(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, driveState : DriveState.Value) : VehicleData = {
- VehicleData(CommonFieldData(loc, faction, 0), health, driveState, false, UtilityVehicleData(0), None)
+ VehicleData(loc, CommonFieldData(faction, 0), health, driveState, false, UtilityVehicleData(0), None)
}
def apc_nc(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.apc_weapon_systemc_nc, weapon1_guid, 11,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemd_nc, weapon4_guid, 14,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo4_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo4_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def apc_tr(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.apc_weapon_systemc_tr, weapon1_guid, 11,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemd_tr, weapon4_guid, 14,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def apc_vs(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.apc_weapon_systemc_vs, weapon1_guid, 11,
- WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_weapon_systemd_vs, weapon4_guid, 14,
- WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo4_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo4_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def aurora(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo11_guid : PlanetSideGUID, ammo12_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo21_guid : PlanetSideGUID, ammo22_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.aurora_weapon_systema, weapon1_guid, 5,
- WeaponData(0x6, 0x8, 0, ObjectClass.fluxpod_ammo, ammo11_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.fluxpod_ammo, ammo11_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.aurora_weapon_systemb, weapon2_guid, 6,
- WeaponData(0x6, 0x8, 0, ObjectClass.fluxpod_ammo, ammo21_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.fluxpod_ammo, ammo21_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def battlewagon(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.battlewagon_weapon_systema, weapon1_guid, 5,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.battlewagon_weapon_systemb, weapon2_guid, 6,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo2_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.battlewagon_weapon_systemc, weapon3_guid, 7,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo3_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.battlewagon_weapon_systemd, weapon4_guid, 8,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def dropship(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.cannon_dropship_20mm, weapon1_guid, 12,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.cannon_dropship_20mm, weapon2_guid, 13,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.dropship_rear_turret, weapon3_guid, 14,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def flail(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID, terminal_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.flail_weapon, weapon_guid, 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.ancient_ammo_vehicle, ammo_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.ancient_ammo_vehicle, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
- InventoryItemData(ObjectClass.targeting_laser_dispenser, terminal_guid, 2, CommonTerminalData(faction, 2)) :: Nil
+ InventoryItemData(ObjectClass.targeting_laser_dispenser, terminal_guid, 2, CommonFieldData(faction, 2)(false)) :: Nil
))
)
}
def fury(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.fury_weapon_systema, weapon_guid, 1,
- WeaponData(0x4, 0x8, ObjectClass.hellfire_ammo, ammo_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x4, 0x8, ObjectClass.hellfire_ammo, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def galaxy_gunship(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.galaxy_gunship_cannon, weapon1_guid, 6,
- WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.galaxy_gunship_cannon, weapon2_guid, 7,
- WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.galaxy_gunship_tailgun, weapon3_guid, 8,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.galaxy_gunship_gun, weapon4_guid, 9,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo4_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo4_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.galaxy_gunship_gun, weapon5_guid, 10,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo5_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo5_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def liberator(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.liberator_weapon_system, weapon1_guid, 3,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.liberator_bomb_bay, weapon2_guid, 4,
- WeaponData(0x6, 0x8, 0, ObjectClass.liberator_bomb, ammo2_guid, 0, AmmoBoxData(8), ObjectClass.liberator_bomb, ammo3_guid, 1, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.liberator_bomb, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.liberator_bomb, ammo3_guid, 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.liberator_25mm_cannon, weapon3_guid, 5,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_25mm, ammo4_guid, 0 ,AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_25mm, ammo4_guid, 0 ,CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def lightgunship(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.lightgunship_weapon_system, weapon_guid, 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.reaver_rocket, ammo2_guid,1, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.reaver_rocket, ammo2_guid,1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def lightning(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.lightning_weapon_system, weapon_guid, 1,
- WeaponData(0x4, 0x8, 0, ObjectClass.bullet_75mm, ammo1_guid, 0, AmmoBoxData(0x0), ObjectClass.bullet_12mm, ammo2_guid, 1, AmmoBoxData(0x0))
+ WeaponData(0x4, 0x8, 0, ObjectClass.bullet_75mm, ammo1_guid, 0, CommonFieldData()(false), ObjectClass.bullet_12mm, ammo2_guid, 1, CommonFieldData()(false))
) :: Nil)
)
)
}
def lodestar(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, repair1_guid : PlanetSideGUID, repair2_guid : PlanetSideGUID, veh_rearm1_guid : PlanetSideGUID, veh_rearm2_guid : PlanetSideGUID, bfr_rearm1_guid : PlanetSideGUID, bfr_rearm2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(List(
- InternalSlot(ObjectClass.lodestar_repair_terminal, repair1_guid, 2, CommonTerminalData(faction, 2)),
- InternalSlot(ObjectClass.lodestar_repair_terminal, repair2_guid, 3, CommonTerminalData(faction, 2)),
- InternalSlot(ObjectClass.multivehicle_rearm_terminal, veh_rearm1_guid, 4, CommonTerminalData(faction, 2)),
- InternalSlot(ObjectClass.multivehicle_rearm_terminal, veh_rearm2_guid, 5, CommonTerminalData(faction, 2)),
- InternalSlot(ObjectClass.bfr_rearm_terminal, bfr_rearm1_guid, 6, CommonTerminalData(faction, 2)),
- InternalSlot(ObjectClass.bfr_rearm_terminal, bfr_rearm2_guid, 7, CommonTerminalData(faction, 2))
+ InternalSlot(ObjectClass.lodestar_repair_terminal, repair1_guid, 2, CommonFieldData(faction, 2)(false)),
+ InternalSlot(ObjectClass.lodestar_repair_terminal, repair2_guid, 3, CommonFieldData(faction, 2)(false)),
+ InternalSlot(ObjectClass.multivehicle_rearm_terminal, veh_rearm1_guid, 4, CommonFieldData(faction, 2)(false)),
+ InternalSlot(ObjectClass.multivehicle_rearm_terminal, veh_rearm2_guid, 5, CommonFieldData(faction, 2)(false)),
+ InternalSlot(ObjectClass.bfr_rearm_terminal, bfr_rearm1_guid, 6, CommonFieldData(faction, 2)(false)),
+ InternalSlot(ObjectClass.bfr_rearm_terminal, bfr_rearm2_guid, 7, CommonFieldData(faction, 2)(false))
)))
)
}
def magrider(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.particle_beam_magrider, weapon1_guid, 2,
- WeaponData(0x6, 0x8, 0, ObjectClass.pulse_battery, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.pulse_battery, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.heavy_rail_beam_magrider, weapon2_guid, 3,
- WeaponData(0x6, 0x8, 0, ObjectClass.heavy_rail_beam_battery, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.heavy_rail_beam_battery, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def mediumtransport(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID): VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.mediumtransport_weapon_systemA, weapon1_guid, 5,
- WeaponData(0x6, 0x8, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, ObjectClass.bullet_20mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.mediumtransport_weapon_systemB, weapon2_guid, 6,
- WeaponData(0x6, 0x8, ObjectClass.bullet_20mm, ammo2_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, ObjectClass.bullet_20mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def mosquito(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.rotarychaingun_mosquito, weapon_guid, 1,
- WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def phantasm(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)), None)(VehicleFormat.Variant)
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0), None)
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)), None)(VehicleFormat.Variant)
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0), None)
}
def prowler(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.prowler_weapon_systemA, weapon1_guid, 3,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_105mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_105mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.prowler_weapon_systemB, weapon2_guid, 4,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def quadassault(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.quadassault_weapon_system, weapon_guid, 1,
- WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def quadstealth(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, false, false, false, None, None)(VehicleFormat.Normal)
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false, None)
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, false, false, false, None, None)(VehicleFormat.Normal)
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false, None)
}
def router(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, terminal_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.Mobile, false, VariantVehicleData(0),
Some(InventoryData(
- InventoryItemData(ObjectClass.teleportpad_terminal, terminal_guid, 1, CommonTerminalData(faction, 2)) :: Nil
+ InventoryItemData(ObjectClass.teleportpad_terminal, terminal_guid, 1, CommonFieldData(faction, 2)(false)) :: Nil
))
)
}
def skyguard(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.skyguard_weapon_system, weapon_guid, 2,
- WeaponData(0x6, 0x8, 0, ObjectClass.skyguard_flak_cannon_ammo, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.bullet_12mm, ammo2_guid, 1, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.skyguard_flak_cannon_ammo, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.bullet_12mm, ammo2_guid, 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def switchblade(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, driveState : DriveState.Value, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.scythe, weapon_guid, 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.ancient_ammo_vehicle, ammo1_guid, 0, AmmoBoxData(0x8), ObjectClass.ancient_ammo_vehicle, ammo2_guid, 1, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.ancient_ammo_vehicle, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.ancient_ammo_vehicle, ammo2_guid, 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def threemanheavybuggy(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.chaingun_p, weapon1_guid, 3,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo1_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.grenade_launcher_marauder, weapon2_guid, 4,
- WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo2_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.heavy_grenade_mortar, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def thunderer(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.thunderer_weapon_systema, weapon1_guid, 5,
- WeaponData(0x6, 0x8, 0, ObjectClass.gauss_cannon_ammo, ammo1_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.gauss_cannon_ammo, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.thunderer_weapon_systemb, weapon2_guid, 6,
- WeaponData(0x6, 0x8, 0, ObjectClass.gauss_cannon_ammo, ammo2_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.gauss_cannon_ammo, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def two_man_assault_buggy(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.chaingun_p, weapon_guid, 2,
- WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, ObjectClass.bullet_12mm, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def twomanheavybuggy(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.advanced_missile_launcher_t, weapon_guid, 2,
- WeaponData(0x6, 0x8, 0, ObjectClass.firebird_missile, ammo_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.firebird_missile, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def twomanhoverbuggy(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.flux_cannon_thresher, weapon_guid, 2,
- WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo_guid, 0, AmmoBoxData(0x8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def vanguard(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false,
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None,
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false,
Some(InventoryData(
InventoryItemData(ObjectClass.vanguard_weapon_system, weapon_guid, 2,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_150mm, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.bullet_20mm, ammo2_guid, 1, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_150mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.bullet_20mm, ammo2_guid, 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def vulture(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 2), health, DriveState.State7, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.vulture_nose_weapon_system, weapon1_guid, 3,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo1_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_35mm, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.vulture_bomb_bay, weapon2_guid, 4,
- WeaponData(0x6, 0x8, 0, ObjectClass.liberator_bomb, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.liberator_bomb, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) ::
InventoryItemData(ObjectClass.vulture_tail_cannon, weapon3_guid, 5,
- WeaponData(0x6, 0x8, 0, ObjectClass.bullet_25mm, ammo3_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.bullet_25mm, ammo3_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
}
def wasp(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = {
- //VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
- VehicleData(CommonFieldData(loc, faction, 0), health, DriveState.Mobile, false, VariantVehicleData(0),
+ //VehicleData(loc, CommonFieldData(faction, 0), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)),
+ VehicleData(loc, CommonFieldData(faction, 0), health, DriveState.Mobile, false, VariantVehicleData(0),
Some(InventoryData(
InventoryItemData(ObjectClass.wasp_weapon_system, weapon_guid, 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.wasp_gun_ammo, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.wasp_rocket_ammo, ammo2_guid, 0, AmmoBoxData(8))
+ WeaponData(0x6, 0x8, 0, ObjectClass.wasp_gun_ammo, ammo1_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2), ObjectClass.wasp_rocket_ammo, ammo2_guid, 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
) :: Nil
))
)
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/REKData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/REKData.scala
index eabf66cb..13f6a4d9 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/REKData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/REKData.scala
@@ -8,35 +8,33 @@ import shapeless.{::, HNil}
/**
* na
- * @param unk1 na
- * @param unk2 na;
+ * @param data na
+ * @param unk na;
* defaults to 0
* @see `DetailedREKData`
*/
-final case class REKData(unk1 : Int,
- unk2 : Int,
- unk3 : Int = 0
+final case class REKData(data : CommonFieldData,
+ unk : Int = 0
) extends ConstructorData {
override def bitsize : Long = 50L
}
object REKData extends Marshallable[REKData] {
implicit val codec : Codec[REKData] = (
- ("unk1" | uint4L) ::
- ("unk2" | uint4L) ::
- uint(28) ::
- ("unk3" | uint4L) ::
+ ("data" | CommonFieldData.codec2) ::
+ uint8 ::
+ ("unk" | uint8) ::
uint(10)
).exmap[REKData] (
{
- case unk1 :: unk2 :: 0 :: unk3 :: 0 :: HNil =>
- Attempt.successful(REKData(unk1, unk2, unk3))
- case _ :: _ :: _ :: _ :: _ :: HNil =>
- Attempt.failure(Err("invalid rek data format"))
+ case data :: 0 :: unk :: 0 :: HNil =>
+ Attempt.successful(REKData(data, unk))
+ case data =>
+ Attempt.failure(Err(s"invalid rek data format - $data"))
},
{
- case REKData(unk1, unk2, unk3) =>
- Attempt.successful(unk1 :: unk2 :: 0 :: unk3 :: 0 :: HNil)
+ case REKData(data, unk) =>
+ Attempt.successful(data :: 0 :: unk :: 0 :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallDeployableData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallDeployableData.scala
deleted file mode 100644
index c6ac9cd2..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallDeployableData.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import net.psforever.types.PlanetSideEmpire
-import scodec.Codec
-import scodec.codecs._
-
-/**
- * A representation of simple objects that are spawned by the adaptive construction engine.
- * //@param deploy data common to objects spawned by the (advanced) adaptive construction engine
- */
-final case class SmallDeployableData(pos : PlacementData,
- faction : PlanetSideEmpire.Value,
- bops : Boolean,
- destroyed : Boolean,
- unk1 : Int,
- jammered : Boolean,
- unk2 : Boolean,
- owner_guid : PlanetSideGUID) extends ConstructorData {
- override def bitsize : Long = {
- val posSize = pos.bitsize
- 24 + posSize
- }
-}
-
-object SmallDeployableData extends Marshallable[SmallDeployableData] {
- def apply(pos : PlacementData, faction : PlanetSideEmpire.Value, unk1 : Int, jammered : Boolean, unk2 : Boolean) : SmallDeployableData = {
- SmallDeployableData(pos, faction, false, false, unk1, jammered, unk2, PlanetSideGUID(0))
- }
-
- implicit val codec : Codec[SmallDeployableData] = (
- ("pos" | PlacementData.codec) ::
- ("faction" | PlanetSideEmpire.codec) ::
- ("bops" | bool) ::
- ("destroyed" | bool) ::
- ("unk1" | uint2L) :: //3 - na, 2 - common, 1 - na, 0 - common?
- ("jammered" | bool) ::
- ("unk2" | bool) ::
- ("owner_guid" | PlanetSideGUID.codec)
- ).as[SmallDeployableData]
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallTurretData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallTurretData.scala
index 464e2e02..f02df9dd 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallTurretData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/SmallTurretData.scala
@@ -3,6 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
import scodec.codecs._
import scodec.{Attempt, Codec, Err}
import shapeless.{::, HNil}
@@ -20,7 +21,7 @@ import shapeless.{::, HNil}
* @param health the amount of health the object has, as a percentage of a filled bar
* @param internals data regarding the mounted weapon
*/
-final case class SmallTurretData(deploy : SmallDeployableData,
+final case class SmallTurretData(deploy : CommonFieldDataWithPlacement,
health : Int,
internals : Option[InventoryData] = None
) extends ConstructorData {
@@ -44,49 +45,11 @@ object SmallTurretData extends Marshallable[SmallTurretData] {
* @param internals data regarding the mounted weapon
* @return a `SmallTurretData` object
*/
- def apply(deploy : SmallDeployableData, health : Int, internals : InventoryData) : SmallTurretData =
+ def apply(deploy : CommonFieldDataWithPlacement, health : Int, internals : InventoryData) : SmallTurretData =
new SmallTurretData(deploy, health, Some(internals))
- /**
- * Prefabricated weapon data for both Spitfires (`spitfire_turret`) and Shadow Turrets (`spitfire_cloaked`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def spitfire(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.spitfire_weapon, wep_guid, 0,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.spitfire_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
-
- /**
- * Prefabricated weapon data for Cerebus turrets (`spitfire_aa`).
- * @param wep_guid the uid to assign to the weapon
- * @param wep_unk1 na;
- * used by `WeaponData`
- * @param ammo_guid the uid to assign to the ammo
- * @param wep_unk2 na;
- * used by `WeaponData`
- * @param ammo_unk na;
- * used by `AmmoBoxData`
- * @return an `InternalSlot` object
- */
- def cerebus(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
- InternalSlot(ObjectClass.spitfire_aa_weapon, wep_guid, 0,
- WeaponData(wep_unk1, wep_unk2, ObjectClass.spitfire_aa_ammo, ammo_guid, 0,
- AmmoBoxData(ammo_unk)
- )
- )
-
implicit val codec : Codec[SmallTurretData] = (
- ("deploy" | SmallDeployableData.codec) ::
+ ("deploy" | CommonFieldDataWithPlacement.codec2) ::
("health" | uint8L) ::
uintL(7) ::
uint4L ::
@@ -103,8 +66,8 @@ object SmallTurretData extends Marshallable[SmallTurretData] {
}
Attempt.successful(SmallTurretData(deploy, newHealth, newInternals))
- case _ =>
- Attempt.failure(Err("invalid small turret data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid small turret data format - $data"))
},
{
case SmallTurretData(deploy, health, internals) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/TRAPData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/TRAPData.scala
index 8128965b..830d06a0 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/TRAPData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/TRAPData.scala
@@ -12,7 +12,7 @@ import shapeless.{::, HNil}
* @param deploy data common to objects spawned by the (advanced) adaptive construction engine
* @param health the amount of health the object has, as a percentage of a filled bar
*/
-final case class TRAPData(deploy : SmallDeployableData,
+final case class TRAPData(deploy : CommonFieldDataWithPlacement,
health : Int
) extends ConstructorData {
override def bitsize : Long = {
@@ -22,7 +22,7 @@ final case class TRAPData(deploy : SmallDeployableData,
object TRAPData extends Marshallable[TRAPData] {
implicit val codec : Codec[TRAPData] = (
- ("deploy" | SmallDeployableData.codec) ::
+ ("deploy" | CommonFieldDataWithPlacement.codec2) ::
("health" | uint8L) ::
uint(7) ::
uint4L ::
@@ -32,8 +32,8 @@ object TRAPData extends Marshallable[TRAPData] {
case deploy :: health :: 0 :: 15 :: 0 :: HNil =>
Attempt.successful(TRAPData(deploy, health))
- case _ =>
- Attempt.failure(Err("invalid trap data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid trap data format - $data"))
},
{
case TRAPData(deploy, health) =>
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadData.scala
deleted file mode 100644
index b4ed0f0b..00000000
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadData.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game.objectcreate
-
-import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import scodec.{Attempt, Codec, Err}
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-/**
- * A representation of the telepad portion of `ObjectCreateMessage` packet data.
- * This data will help construct the "cosntruction tool"
- * that can be obtained from the Router vehicle - the Router telepad.
- * It issued to construct a bidirectional teleportation point associated with a Router if that Router is deployed.
- * @param unk na
- * @param router_guid the Router
- */
-final case class TelepadData(unk : Int, router_guid : Option[PlanetSideGUID]) extends ConstructorData {
- override def bitsize : Long = {
- val rguidSize = if(router_guid.nonEmpty) 16 else 0
- 34L + rguidSize
- }
-}
-
-object TelepadData extends Marshallable[TelepadData] {
- def apply(unk : Int) : TelepadData = TelepadData(unk, None)
-
- def apply(unk : Int, router_guid : PlanetSideGUID) : TelepadData = TelepadData(unk, Some(router_guid))
-
- implicit val codec : Codec[TelepadData] = (
- ("unk" | uint(6)) ::
- optional(bool, "router_guid" | PlanetSideGUID.codec) ::
- uint(27)
- ).exmap[TelepadData] (
- {
- case unk :: rguid :: 0 :: HNil =>
- Attempt.successful(TelepadData(unk, rguid))
- case _ =>
- Attempt.failure(Err("invalid telepad format"))
- },
- {
- case TelepadData(unk, rguid) =>
- Attempt.successful(unk :: rguid :: 0 :: HNil)
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadDeployableData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadDeployableData.scala
index 369f641a..160bc490 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadDeployableData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/TelepadDeployableData.scala
@@ -2,54 +2,41 @@
package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
-import net.psforever.packet.game.PlanetSideGUID
-import net.psforever.types.PlanetSideEmpire
-import scodec.Codec
+import scodec.{Attempt, Codec, Err}
import scodec.codecs._
+import shapeless.{::, HNil}
/**
* A representation of simple objects that are spawned by the adaptive construction engine.
- * @param pos na
- * @param faction na
- * @param bops na
- * @param destroyed na
+ * @param data data common to game objects
* @param unk1 na
* @param unk2 na
- * @param router_guid the associated Router vehicle;
- * this is an essential non-blank (16u 0x0) field;
- * a blanked field will cause the client to crash
- * @param owner_guid the owner of this telepad
- * @param unk3 na
- * @param unk4 na
*/
-//TODO might be CommonFieldData
-final case class TelepadDeployableData(pos : PlacementData,
- faction : PlanetSideEmpire.Value,
- bops : Boolean,
- destroyed : Boolean,
+final case class TelepadDeployableData(data : CommonFieldData,
unk1 : Int,
- unk2 : Boolean,
- router_guid : PlanetSideGUID,
- owner_guid : PlanetSideGUID,
- unk3 : Int,
- unk4 : Int) extends ConstructorData {
+ unk2 : Int) extends ConstructorData {
override def bitsize : Long = {
- val posSize = pos.bitsize
- 59 + posSize
+ 20L + data.bitsize
}
}
object TelepadDeployableData extends Marshallable[TelepadDeployableData] {
implicit val codec : Codec[TelepadDeployableData] = (
- ("pos" | PlacementData.codec) ::
- ("faction" | PlanetSideEmpire.codec) ::
- ("bops" | bool) ::
- ("destroyed" | bool) ::
- ("unk1" | uint2L) :: //3 - na, 2 - common, 1 - na, 0 - common?
- ("unk2" | bool) ::
- ("router_guid" | PlanetSideGUID.codec) ::
- ("owner_guid" | PlanetSideGUID.codec) ::
- ("unk3" | uint16L) ::
- ("unk4" | uint4)
- ).as[TelepadDeployableData]
+ ("deploy" | CommonFieldData.codec) ::
+ ("unk1" | uint8) ::
+ uint8 ::
+ ("unk2" | uint4)
+ ).exmap[TelepadDeployableData] (
+ {
+ case data :: unk1 :: 0 :: unk2 :: HNil =>
+ Attempt.successful(TelepadDeployableData(data, unk1, unk2))
+
+ case data =>
+ Attempt.failure(Err(s"invalid telepad data format - $data"))
+ },
+ {
+ case TelepadDeployableData(data, unk1, unk2) =>
+ Attempt.successful(data :: unk1 :: 0 :: unk2 :: HNil)
+ }
+ )
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/TerminalData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/TerminalData.scala
new file mode 100644
index 00000000..65687cc0
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/TerminalData.scala
@@ -0,0 +1,21 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.packet.game.objectcreate
+
+import net.psforever.packet.game.PlanetSideGUID
+
+/**
+ * A representation of an object that can be interacted with when using a variety of terminals.
+ * This object is generally invisible.
+ */
+object TerminalData {
+ /**
+ * Overloaded constructor for a type of common terminal.
+ * @param cls the code for the type of object being constructed
+ * @param guid the GUID this object will be assigned
+ * @param parentSlot a parent-defined slot identifier that explains where the child is to be attached to the parent
+ * @param terminal the `TerminalData`
+ * @return an `InternalSlot` object
+ */
+ def apply(cls : Int, guid : PlanetSideGUID, parentSlot : Int, terminal : CommonFieldData) : InternalSlot =
+ InternalSlot(cls, guid, parentSlot, terminal)
+}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/TrackedProjectileData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/TrackedProjectileData.scala
index b2420ca4..dece6e29 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/TrackedProjectileData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/TrackedProjectileData.scala
@@ -1,86 +1,57 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game.objectcreate
-import net.psforever.packet.Marshallable
+import net.psforever.packet.{Marshallable, PacketHelpers}
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
+object TrackedProjectile extends Enumeration {
+ type Type = Value
+
+ val Meteor = Value(32)
+ val WaspRocket = Value(208)
+ val Sparrow = Value(3355579)
+ val OICW = Value(3355587)
+ val Striker = Value(6710918)
+ val HunterSeeker = Value(10131913)
+ val Starfire = Value(10131961)
+
+ implicit val codec = PacketHelpers.createEnumerationCodec(this, uint24)
+}
+
/**
* A representation of a projectile that the server must intentionally convey to players other than the shooter.
- * @param pos where and how the projectile is oriented
- * @param unk1 na
+ * @param data na
* @param unk2 na;
* data specific to the type of projectile(?)
+ * @param unk3 na
*/
-final case class TrackedProjectileData(pos : PlacementData,
- unk1 : Int,
- unk2 : Int
+final case class TrackedProjectileData(data : CommonFieldDataWithPlacement,
+ unk2 : TrackedProjectile.Value,
+ unk3 : Int = 0
) extends ConstructorData {
- override def bitsize : Long = 56L + pos.bitsize
+ override def bitsize : Long = 33L + data.bitsize
}
object TrackedProjectileData extends Marshallable[TrackedProjectileData] {
- final val oicw_projectile_data = 3355587
- final val striker_missile_targetting_projectile_data = 6710918
- final val hunter_seeker_missile_projectile_data = 10131913
- final val starfire_projectile_data = 10131961
-
- /**
- * Overloaded constructor specifically for OICW projectiles.
- * @param pos where and how the projectile is oriented
- * @param unk na
- * @return a `TrackedProjectileData` object
- */
- def oicw(pos : PlacementData, unk : Int) : TrackedProjectileData =
- new TrackedProjectileData(pos, unk, oicw_projectile_data)
-
- /**
- * Overloaded constructor specifically for Striker projectiles.
- * @param pos where and how the projectile is oriented
- * @param unk na
- * @return a `TrackedProjectileData` object
- */
- def striker(pos : PlacementData, unk : Int) : TrackedProjectileData =
- new TrackedProjectileData(pos, unk, striker_missile_targetting_projectile_data)
-
- /**
- * Overloaded constructor specifically for Hunter Seeker (Phoenix) projectiles.
- * @param pos where and how the projectile is oriented
- * @param unk na
- * @return a `TrackedProjectileData` object
- */
- def hunter_seeker(pos : PlacementData, unk : Int) : TrackedProjectileData =
- new TrackedProjectileData(pos, unk, hunter_seeker_missile_projectile_data)
-
- /**
- * Overloaded constructor specifically for Starfire projectiles.
- * @param pos where and how the projectile is oriented
- * @param unk na
- * @return a `TrackedProjectileData` object
- */
- def starfire(pos : PlacementData, unk : Int) : TrackedProjectileData =
- new TrackedProjectileData(pos, unk, starfire_projectile_data)
-
implicit val codec : Codec[TrackedProjectileData] = (
- ("pos" | PlacementData.codec) ::
- ("unk1" | uint(3)) ::
- uint4L ::
- uint16L ::
- ("unk2" | uint24) ::
- uint4L ::
- uint(5)
+ ("data" | CommonFieldDataWithPlacement.codec) ::
+ ("unk2" | TrackedProjectile.codec) ::
+ uint4 ::
+ uint(3) ::
+ uint2
).exmap[TrackedProjectileData] (
{
- case pos :: unk1 :: 4 :: 0 :: unk2 :: 4 :: 0 :: HNil =>
- Attempt.successful(TrackedProjectileData(pos, unk1, unk2))
+ case data :: unk2 :: 4 :: unk3 :: 0 :: HNil =>
+ Attempt.successful(TrackedProjectileData(data, unk2, unk3))
- case _ =>
- Attempt.failure(Err("invalid projectile data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid projectile data format - $data"))
},
{
- case TrackedProjectileData(pos, unk1, unk2) =>
- Attempt.successful(pos :: unk1 :: 4 :: 0 :: unk2 :: 4 :: 0 :: HNil)
+ case TrackedProjectileData(data, unk2, unk3) =>
+ Attempt.successful(data :: unk2 :: 4 :: unk3 :: 0 :: HNil)
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/VehicleData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/VehicleData.scala
index a3d271c8..4030da21 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/VehicleData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/VehicleData.scala
@@ -7,7 +7,7 @@ import scodec.Attempt.{Failure, Successful}
import scodec.{Attempt, Codec, Err}
import shapeless.HNil //note: do not import shapeless.:: here; it messes up List's :: functionality
import scodec.codecs._
-import net.psforever.types.{DriveState, PlanetSideEmpire}
+import net.psforever.types.DriveState
import scala.collection.mutable.ListBuffer
@@ -27,7 +27,7 @@ object VehicleFormat extends Enumeration {
/**
* A basic `Trait` connecting all of the vehicle data formats (excepting `Normal`/`None`).
*/
-sealed trait SpecificVehicleData extends StreamBitSize
+sealed abstract class SpecificVehicleData(val format : VehicleFormat.Value) extends StreamBitSize
/**
* The format of vehicle data for the type of vehicles that are considered "utility."
@@ -36,7 +36,7 @@ sealed trait SpecificVehicleData extends StreamBitSize
* the advanced mobile station.
* @param unk na
*/
-final case class UtilityVehicleData(unk : Int) extends SpecificVehicleData {
+final case class UtilityVehicleData(unk : Int) extends SpecificVehicleData(VehicleFormat.Utility) {
override def bitsize : Long = 6L
}
@@ -45,24 +45,21 @@ final case class UtilityVehicleData(unk : Int) extends SpecificVehicleData {
* This category includes all flying vehicles and the ancient cavern vehicles.
* @param unk na
*/
-final case class VariantVehicleData(unk : Int) extends SpecificVehicleData {
+final case class VariantVehicleData(unk : Int) extends SpecificVehicleData(VehicleFormat.Variant) {
override def bitsize : Long = 8L
}
/**
* A representation of a generic vehicle.
* @param pos where the vehicle is and how it is oriented in the game world
- * @param faction the faction that is aligned with this vehicle
- * @param bops this vehicle belongs to the Black Ops, regardless of the faction field;
- * activates the green camo and adjusts permissions
- * @param destroyed this vehicle has ben destroyed;
- * it's health should be less than 3/255, or 0%
- * @param unk1 na. Valid values seem to be 0-3. Anything higher spawns a completely broken NC vehicle with no guns that can't move
- * @param jammered this vehicle is under the influence of a jammer grenade
- * @param unk2 na
- * @param owner_guid the vehicle's (official) owner;
- * verified as a living player in the game world on the same continent as the vehicle;
- * sitting in the driver's seat or a `PlanetSideAttributeMessage` of type 21 can influence
+ * @param data common vehicle field data:
+ * -bops - this vehicle belongs to the Black Ops, regardless of the faction field;
+ * activates the green camo and adjusts permissions
+ * -destroyed - this vehicle has ben destroyed;
+ * health should be less than 3/255, or 0%
+ * -jammered - vehicles will not be jammered by setting this field
+ * -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 seat
* @param unk3 na
* @param health the amount of health the vehicle has, as a percentage of a filled bar (255)
* @param unk4 na
@@ -82,13 +79,7 @@ final case class VariantVehicleData(unk : Int) extends SpecificVehicleData {
* defaults to `Normal`
*/
final case class VehicleData(pos : PlacementData,
- faction : PlanetSideEmpire.Value,
- bops : Boolean,
- destroyed : Boolean,
- unk1 : Int,
- jammered : Boolean,
- unk2 : Boolean,
- owner_guid : PlanetSideGUID,
+ data : CommonFieldData,
unk3 : Boolean,
health : Int,
unk4 : Boolean,
@@ -103,9 +94,10 @@ final case class VehicleData(pos : PlacementData,
override def bitsize : Long = {
//factor guard bool values into the base size, not its corresponding optional field
val posSize : Long = pos.bitsize
+ val dataSize : Long = data.bitsize
val extraBitsSize : Long = if(vehicle_format_data.isDefined) { vehicle_format_data.get.bitsize } else { 0L }
val inventorySize = if(inventory.isDefined) { inventory.get.bitsize } else { 0L }
- 47L + posSize + extraBitsSize + inventorySize
+ 23L + posSize + dataSize + extraBitsSize + inventorySize
}
}
@@ -118,9 +110,8 @@ object VehicleData extends Marshallable[VehicleData] {
* @param cloak if a vehicle (that can cloak) is cloaked
* @param inventory the seats, mounted weapons, and utilities (such as terminals) that are currently included
*/
- def apply(basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, inventory : Option[InventoryData]) : VehicleData = {
- VehicleData(basic.pos, basic.faction, basic.bops, basic.destroyed, 0, basic.jammered, false, basic.player_guid,
- false, health, false, false, driveState, false, false, cloak, None, inventory)(VehicleFormat.Normal)
+ def apply(pos : PlacementData, basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, inventory : Option[InventoryData]) : VehicleData = {
+ VehicleData(pos, basic, false, health, false, false, driveState, false, false, cloak, None, inventory)(VehicleFormat.Normal)
}
/**
@@ -131,9 +122,8 @@ object VehicleData extends Marshallable[VehicleData] {
* @param cloak if a vehicle (that can cloak) is cloaked
* @param inventory the seats, mounted weapons, and utilities (such as terminals) that are currently included
*/
- def apply(basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, format : UtilityVehicleData, inventory : Option[InventoryData]) : VehicleData = {
- VehicleData(basic.pos, basic.faction, basic.bops, basic.destroyed, 0, basic.jammered, false, basic.player_guid,
- false, health, false, false, driveState, false, false, cloak, Some(format), inventory)(VehicleFormat.Utility)
+ def apply(pos : PlacementData, basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, format : UtilityVehicleData, inventory : Option[InventoryData]) : VehicleData = {
+ VehicleData(pos, basic, false, health, false, false, driveState, false, false, cloak, Some(format), inventory)(VehicleFormat.Utility)
}
/**
@@ -144,9 +134,8 @@ object VehicleData extends Marshallable[VehicleData] {
* @param cloak if a vehicle (that can cloak) is cloaked
* @param inventory the seats, mounted weapons, and utilities (such as terminals) that are currently included
*/
- def apply(basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, format : VariantVehicleData, inventory : Option[InventoryData]) : VehicleData = {
- VehicleData(basic.pos, basic.faction, basic.bops, basic.destroyed, 0, basic.jammered, false, basic.player_guid,
- false, health, false, false, driveState, false, false, cloak, Some(format), inventory)(VehicleFormat.Variant)
+ def apply(pos : PlacementData, basic : CommonFieldData, health : Int, driveState : DriveState.Value, cloak : Boolean, format : VariantVehicleData, inventory : Option[InventoryData]) : VehicleData = {
+ VehicleData(pos, basic, false, health, false, false, driveState, false, false, cloak, Some(format), inventory)(VehicleFormat.Variant)
}
import net.psforever.packet.game.objectcreate.{PlayerData => Player_Data}
@@ -163,7 +152,7 @@ object VehicleData extends Marshallable[VehicleData] {
* used to calculate the padding value for the player's name in `CharacterAppearanceData`
* @return a `PlayerData` object
*/
- def PlayerData(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type, accumulative : Long) : Player_Data = {
+ def PlayerData(basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, inventory : InventoryData, drawn_slot : DrawnSlot.Type, accumulative : Long) : Player_Data = {
val appearance = basic_appearance(CumulativeSeatedPlayerNamePadding(accumulative))
Player_Data(None, appearance, character_data(appearance.b.backpack, true), Some(inventory), drawn_slot)(false)
}
@@ -179,12 +168,15 @@ object VehicleData extends Marshallable[VehicleData] {
* used to calculate the padding value for the player's name in `CharacterAppearanceData`
* @return a `PlayerData` object
*/
- def PlayerData(basic_appearance : (Int)=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type, accumulative : Long) : Player_Data = {
+ def PlayerData(basic_appearance : Int=>CharacterAppearanceData, character_data : (Boolean,Boolean)=>CharacterData, drawn_slot : DrawnSlot.Type, accumulative : Long) : Player_Data = {
val appearance = basic_appearance(CumulativeSeatedPlayerNamePadding(accumulative))
Player_Data.apply(None, appearance, character_data(appearance.b.backpack, true), None, drawn_slot)(false)
}
- private val driveState8u = PacketHelpers.createEnumerationCodec(DriveState, uint8L)
+ private val driveState8u = uint8.xmap[DriveState.Value] (
+ n => DriveState(n),
+ n => n.id
+ )
/**
* `Codec` for the "utility" format.
@@ -241,13 +233,7 @@ object VehicleData extends Marshallable[VehicleData] {
import shapeless.::
(
("pos" | PlacementData.codec) >>:~ { pos =>
- ("faction" | PlanetSideEmpire.codec) ::
- ("bops" | bool) ::
- ("destroyed" | bool) ::
- ("unk1" | uint2L) :: //3 - na, 2 - common, 1 - na, 0 - common?
- ("jammered" | bool) ::
- ("unk2" | bool) ::
- ("owner_guid" | PlanetSideGUID.codec) ::
+ ("data" | CommonFieldData.codec2(false)) ::
("unk3" | bool) ::
("health" | uint8L) ::
("unk4" | bool) :: //usually 0
@@ -261,14 +247,14 @@ object VehicleData extends Marshallable[VehicleData] {
}
).exmap[VehicleData] (
{
- case pos :: faction :: bops :: destroyed :: u1 :: jamd :: u2 :: owner :: u3 :: health :: u4 :: no_mount :: driveState :: u5 :: u6 :: cloak :: format :: inv :: HNil =>
- Attempt.successful(new VehicleData(pos, faction, bops, destroyed, u1, jamd, u2, owner, u3, health, u4, no_mount, driveState, u5, u6, cloak, format, inv)(vehicle_type))
+ case pos :: data :: u3 :: health :: u4 :: no_mount :: driveState :: u5 :: u6 :: cloak :: format :: inv :: HNil =>
+ Attempt.successful(new VehicleData(pos, data, u3, health, u4, no_mount, driveState, u5, u6, cloak, format, inv)(vehicle_type))
- case _ =>
- Attempt.failure(Err("invalid vehicle data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid vehicle data format - $data"))
},
{
- case obj @ VehicleData(pos, faction, bops, destroyed, u1, jamd, u2, owner, u3, health, u4, no_mount, driveState, u5, u6, cloak, format, inv) =>
+ case obj @ VehicleData(pos, data, u3, health, u4, no_mount, driveState, u5, u6, cloak, format, inv) =>
if(obj.vehicle_type == VehicleFormat.Normal && format.nonEmpty) {
Attempt.failure(Err("invalid vehicle data format; variable bits not expected"))
}
@@ -276,11 +262,8 @@ object VehicleData extends Marshallable[VehicleData] {
Attempt.failure(Err(s"invalid vehicle data format; variable bits for ${obj.vehicle_type} expected"))
}
else {
- Attempt.successful(pos :: faction :: bops :: destroyed :: u1 :: jamd :: u2 :: owner :: u3 :: health :: u4 :: no_mount :: driveState :: u5 :: u6 :: cloak :: format :: inv :: HNil)
+ Attempt.successful(pos :: data :: u3 :: health :: u4 :: no_mount :: driveState :: u5 :: u6 :: cloak :: format :: inv :: HNil)
}
-
- case _ =>
- Attempt.failure(Err("invalid vehicle data format"))
}
)
}
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala
index b27e53d8..88b63596 100644
--- a/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala
+++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala
@@ -3,6 +3,7 @@ package net.psforever.packet.game.objectcreate
import net.psforever.packet.Marshallable
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.PlanetSideEmpire
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
@@ -15,32 +16,22 @@ import shapeless.{::, HNil}
* The data for the weapons nests information for the default (current) type of ammunition and number of ammunitions in its magazine(s).
* This ammunition data essentially is the weapon's magazines as numbered slots.
* An "expected" number of ammunition slot data can be passed into the class for the purposes of validating input.
- * @param unk1 na;
+ * @param data na;
* commonly 8
- * @param unk2 na;
- * commonly 12
* @param fire_mode the current mode of weapon's fire;
* zero-indexed
* @param ammo data regarding the currently loaded ammunition type(s)
- * @param mag_capacity implicit;
- * the total number of concurrently-loaded ammunition types allowed in this weapon;
- * concurrent ammunition does not need to be unloaded to be switched;
- * defaults to 1;
- * 0 is invalid;
- * -1 or less ignores the imposed checks
* @see `AmmoBoxData`
*/
-final case class WeaponData(unk1 : Int,
- unk2 : Int,
+final case class WeaponData(data : CommonFieldData,
fire_mode : Int,
- ammo : List[InternalSlot]
- )(implicit val mag_capacity : Int = 1) extends ConstructorData {
+ ammo : List[InternalSlot],
+ unk : Boolean = false
+ ) extends ConstructorData {
override def bitsize : Long = {
- var bitsize : Long = 0L
- for(o <- ammo) {
- bitsize += o.bitsize
- }
- 44L + bitsize
+ val dataSize = data.bitsize
+ val ammoSize : Long = ammo.foldLeft(0L)(_ + _.bitsize)
+ 21L + dataSize + ammoSize //11 + 10 (from InventoryData) + ammo
}
}
@@ -55,8 +46,23 @@ object WeaponData extends Marshallable[WeaponData] {
* @param ammo the ammunition object
* @return a `WeaponData` object
*/
- def apply(unk1 : Int, unk2 : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : AmmoBoxData) : WeaponData =
- new WeaponData(unk1, unk2, 0, InternalSlot(cls, guid, parentSlot, ammo) :: Nil)
+ def apply(unk1 : Int, unk2 : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : CommonFieldData) : WeaponData = {
+ WeaponData(
+ CommonFieldData(
+ PlanetSideEmpire(unk1 & 3),
+ false,
+ false,
+ (unk2 & 8) == 8,
+ None,
+ (unk2 & 4) == 4,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ 0,
+ List(InternalSlot(cls, guid, parentSlot, ammo))
+ )
+ }
/**
* Overloaded constructor for creating `WeaponData` that mandates information about the firemode and a single type of ammunition.
@@ -69,8 +75,23 @@ object WeaponData extends Marshallable[WeaponData] {
* @param ammo the ammunition object
* @return a `WeaponData` object
*/
- def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : AmmoBoxData) : WeaponData =
- WeaponData(unk1, unk2, fire_mode, InternalSlot(cls, guid, parentSlot, ammo) :: Nil)
+ def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : CommonFieldData) : WeaponData = {
+ WeaponData(
+ CommonFieldData(
+ PlanetSideEmpire(unk1 & 3),
+ false,
+ false,
+ (unk2 & 8) == 8,
+ None,
+ (unk2 & 4) == 4,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ fire_mode,
+ List(InternalSlot(cls, guid, parentSlot, ammo))
+ )
+ }
/**
* Overloaded constructor for creating `WeaponData` with two types of ammunition concurrently loaded.
@@ -88,71 +109,59 @@ object WeaponData extends Marshallable[WeaponData] {
* @param ammo2 the second ammunition object
* @return a `WeaponData` object
*/
- def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls1 : Int, guid1 : PlanetSideGUID, slot1 : Int, ammo1 : AmmoBoxData, cls2 : Int, guid2 : PlanetSideGUID, slot2 : Int, ammo2 : AmmoBoxData) : WeaponData =
- WeaponData(unk1, unk2, fire_mode, InternalSlot(cls1, guid1, slot1, ammo1) :: InternalSlot(cls2, guid2, slot2, ammo2) :: Nil)(2)
+ def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls1 : Int, guid1 : PlanetSideGUID, slot1 : Int, ammo1 : CommonFieldData, cls2 : Int, guid2 : PlanetSideGUID, slot2 : Int, ammo2 : CommonFieldData) : WeaponData ={
+ WeaponData(
+ CommonFieldData(
+ PlanetSideEmpire(unk1 & 3),
+ false,
+ false,
+ (unk2 & 8) == 8,
+ None,
+ (unk2 & 4) == 4,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ fire_mode,
+ List(InternalSlot(cls1, guid1, slot1, ammo1), InternalSlot(cls2, guid2, slot2, ammo2))
+ )
+ }
- /**
- * A `Codec` for `WeaponData`.
- * @param mag_capacity the total number of concurrently-loaded ammunition types allowed in this weapon;
- * defaults to 1
- * @return a `WeaponData` object or a `BitVector`
- */
- def codec(mag_capacity : Int = 1) : Codec[WeaponData] = (
- ("unk1" | uintL(3)) ::
- bool :: //weapon refuses to shoot if set (not weapons lock?)
- ("unk2" | uint4L) :: //8 - common; 4 - jammers weapons; 2 - weapon breaks; 1, 0 - safe
- uint(20) ::
- ("fire_mode" | int(3)) :: //TODO size?
+ implicit val codec : Codec[WeaponData] = (
+ ("data" | CommonFieldData.codec) ::
+ ("fire_mode" | int8) ::
bool ::
- bool ::
- ("ammo" | InventoryData.codec) ::
- bool
+ optional(bool, "ammo" | InventoryData.codec) ::
+ ("unk" | bool)
).exmap[WeaponData] (
{
- case unk1 :: false :: unk2 :: 0 :: fmode :: false :: true :: InventoryData(ammo) :: false :: HNil =>
+ case data :: fmode :: false :: Some(InventoryData(ammo)) :: unk :: HNil =>
val magSize = ammo.size
- if(mag_capacity == 0 || magSize == 0) {
+ if(magSize == 0) {
Attempt.failure(Err("weapon must decode some ammunition"))
}
- else if(mag_capacity > 0 && magSize != mag_capacity) {
- Attempt.failure(Err(s"weapon decodes too much or too little ammunition - actual $magSize, expected $mag_capacity"))
- }
else {
- Attempt.successful(WeaponData(unk1, unk2, fmode, ammo)(magSize))
+ Attempt.successful(WeaponData(data, fmode, ammo, unk))
}
- case _ =>
- Attempt.failure(Err("invalid weapon data format"))
+ case data =>
+ Attempt.failure(Err(s"invalid weapon data format - $data"))
},
{
- case obj @ WeaponData(unk1, unk2, fmode, ammo) =>
+ case WeaponData(data, fmode, ammo, unk) =>
val magSize = ammo.size
- val magCapacity = obj.mag_capacity
- if(mag_capacity == 0 || magCapacity == 0 || magSize == 0) {
+ if(magSize == 0) {
Attempt.failure(Err("weapon must encode some ammunition"))
}
else if(magSize >= 255) {
Attempt.failure(Err("weapon encodes too much ammunition (255+ types!)"))
}
- else if(magCapacity < 0 || mag_capacity < 0) {
- Attempt.successful(unk1 :: false :: unk2 :: 0 :: fmode :: false :: true :: InventoryData(ammo) :: false :: HNil)
- }
else {
- if(magCapacity != mag_capacity) {
- Attempt.failure(Err(s"different encoding expectations for amount of ammunition - actual $magCapacity, expected $mag_capacity"))
- }
- else if(magSize != mag_capacity) {
- Attempt.failure(Err(s"weapon encodes wrong amount of ammunition - actual $magSize, expected $mag_capacity"))
- }
- else {
- Attempt.successful(unk1 :: false :: unk2 :: 0 :: fmode :: false :: true :: InventoryData(ammo) :: false :: HNil)
- }
+ Attempt.successful(data :: fmode :: false :: Some(InventoryData(ammo)) :: unk :: HNil)
}
case _ =>
Attempt.failure(Err("invalid weapon data format"))
}
)
-
- implicit val codec : Codec[WeaponData] = codec()
}
diff --git a/common/src/main/scala/net/psforever/types/DriveState.scala b/common/src/main/scala/net/psforever/types/DriveState.scala
index e32c774a..07109a68 100644
--- a/common/src/main/scala/net/psforever/types/DriveState.scala
+++ b/common/src/main/scala/net/psforever/types/DriveState.scala
@@ -1,8 +1,5 @@
package net.psforever.types
-import net.psforever.packet.PacketHelpers
-import scodec.codecs.uint
-
/**
* An `Enumeration` of the mobility states of vehicles.
*
@@ -19,6 +16,5 @@ object DriveState extends Enumeration {
val Deploying = Value(2)
val Deployed = Value(3)
val State7 = Value(7) //unknown; not encountered on a vehicle that can deploy; functions like Mobile
-
- implicit val codec = PacketHelpers.createEnumerationCodec(this, uint(3))
+ val State127 = Value(127) //unknown
}
diff --git a/common/src/test/scala/CosmeticsTest.scala b/common/src/test/scala/CosmeticsTest.scala
new file mode 100644
index 00000000..4d67324d
--- /dev/null
+++ b/common/src/test/scala/CosmeticsTest.scala
@@ -0,0 +1,84 @@
+// Copyright (c) 2019 PSForever
+import net.psforever.packet.game.objectcreate.{Cosmetics, PersonalStyle}
+import org.specs2.mutable._
+import net.psforever.types.Vector3
+
+class CosmeticsTest extends Specification {
+ "Cosmetics" should {
+ "construct" in {
+ Cosmetics()
+ Cosmetics(3)
+ Cosmetics(PersonalStyle.NoHelmet)
+ Cosmetics(Set(PersonalStyle.NoHelmet))
+ Cosmetics(true, false, false, false, false)
+ ok
+ }
+
+ "translate into a numeric value" in {
+ Cosmetics().pstyles mustEqual 0
+ Cosmetics(3).pstyles mustEqual 3
+ Cosmetics(PersonalStyle.NoHelmet).pstyles mustEqual PersonalStyle.NoHelmet.id
+ Cosmetics(Set(PersonalStyle.NoHelmet, PersonalStyle.Earpiece)).pstyles mustEqual PersonalStyle.NoHelmet.id + PersonalStyle.Earpiece.id
+ Cosmetics(true, false, false, false, false).pstyles mustEqual PersonalStyle.NoHelmet.id
+ }
+
+ "translate into a list of cosmetic style tokens" in {
+ Cosmetics().Styles mustEqual Set()
+ Cosmetics(3).Styles mustEqual Set(PersonalStyle.BrimmedCap, PersonalStyle.Earpiece)
+ Cosmetics(PersonalStyle.NoHelmet).Styles mustEqual Set(PersonalStyle.NoHelmet)
+ Cosmetics(Set(PersonalStyle.NoHelmet)).Styles mustEqual Set(PersonalStyle.NoHelmet)
+ Cosmetics(true, false, false, false, false).Styles mustEqual Set(PersonalStyle.NoHelmet)
+ }
+
+ "report containing specific values only" in {
+ val cos = Cosmetics(Set(PersonalStyle.NoHelmet, PersonalStyle.Earpiece))
+ cos.contains(PersonalStyle.NoHelmet) mustEqual true
+ cos.contains(PersonalStyle.Beret) mustEqual false
+ }
+
+ "add values" in {
+ val cos = Cosmetics()
+ cos.Styles mustEqual Set()
+ val cos1 = cos + PersonalStyle.NoHelmet
+ cos1.Styles mustEqual Set(PersonalStyle.NoHelmet)
+ cos1.Styles mustNotEqual cos.Styles
+ val cos2 = cos1 + PersonalStyle.Beret
+ cos2.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret)
+ cos2.Styles mustNotEqual cos.Styles
+ cos2.Styles mustNotEqual cos1.Styles
+ }
+
+ "can not add already included values" in {
+ val cos = Cosmetics(Set(PersonalStyle.NoHelmet, PersonalStyle.Beret))
+ cos.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret)
+ val cos1 = cos + PersonalStyle.Beret
+ cos1.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret)
+ cos ne cos1 mustEqual true
+ }
+
+ "remove values" in {
+ val cos = Cosmetics(Set(PersonalStyle.NoHelmet, PersonalStyle.Beret))
+ cos.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret)
+ val cos1 = cos - PersonalStyle.NoHelmet
+ cos1.Styles mustEqual Set(PersonalStyle.Beret)
+ cos1.Styles mustNotEqual cos.Styles
+ val cos2 = cos1 - PersonalStyle.Beret
+ cos2.Styles mustEqual Set()
+ cos2.Styles mustNotEqual cos.Styles
+ cos2.Styles mustNotEqual cos1.Styles
+ }
+
+ "can not remove un-included or already excluded values" in {
+ val cos = Cosmetics(Set(PersonalStyle.NoHelmet, PersonalStyle.Beret))
+ cos.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret)
+ val cos1 = cos - PersonalStyle.Beret
+ cos1.Styles mustEqual Set(PersonalStyle.NoHelmet)
+
+ val cos2 = cos - PersonalStyle.Beret //again
+ cos2.Styles mustEqual Set(PersonalStyle.NoHelmet)
+
+ val cos3 = cos1 - PersonalStyle.Earpiece
+ cos3.Styles mustEqual Set(PersonalStyle.NoHelmet)
+ }
+ }
+}
diff --git a/common/src/test/scala/game/ObjectCreateBaseTest.scala b/common/src/test/scala/game/ObjectCreateBaseTest.scala
deleted file mode 100644
index c3ebe1bd..00000000
--- a/common/src/test/scala/game/ObjectCreateBaseTest.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game
-
-import org.specs2.mutable._
-import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
-import net.psforever.packet.game.objectcreate._
-import scodec.bits._
-
-class ObjectCreateBaseTest extends Specification {
- val packet217 = hex"17 F8 00 00 00 BC 8C 10 90 3B 45 C6 FA 94 00 9F F0 00 00 40 00 08 C0 44 00 69 00 66 00 66 00 45" //fake data
- val packet218 = hex"18 F8 00 00 00 BC 8C 10 90 3B 45 C6 FA 94 00 9F F0 00 00 40 00 08 C0 44 00 69 00 66 00 66 00 45" //fake data
-
- "ObjectCreateDetailedMessage" should {
- "fail to decode" in {
- //an invalid bit representation will fail to turn into an object
- PacketCoding.DecodePacket(packet217).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 248
- cls mustEqual ObjectClass.avatar
- guid mustEqual PlanetSideGUID(2497)
- parent mustEqual None
- data.isDefined mustEqual false
- case _ =>
- ko
- }
- }
-
- "fail to encode" in {
- //the lack of an object will fail to turn into a bad bitstream
- val msg = ObjectCreateMessage(0L, ObjectClass.avatar, PlanetSideGUID(2497), None, None)
- PacketCoding.EncodePacket(msg).isFailure mustEqual true
- }
- }
-
- "ObjectCreateDetailedMessage" should {
- "fail to decode" in {
- //an invalid bit representation will fail to turn into an object
- PacketCoding.DecodePacket(packet218).require match {
- case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
- len mustEqual 248
- cls mustEqual ObjectClass.avatar
- guid mustEqual PlanetSideGUID(2497)
- parent mustEqual None
- data.isDefined mustEqual false
- case _ =>
- ko
- }
- }
-
- "fail to encode" in {
- //the lack of an object will fail to turn into a bad bitstream
- val msg = ObjectCreateDetailedMessage(0L, ObjectClass.avatar, PlanetSideGUID(2497), None, None)
- PacketCoding.EncodePacket(msg).isFailure mustEqual true
- }
- }
-
- "StreamBitSize" should {
- "have zero size by default" in {
- new StreamBitSize() {}.bitsize mustEqual 0L
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/ACEDataTest.scala b/common/src/test/scala/game/objectcreate/ACEDataTest.scala
deleted file mode 100644
index 980e4d56..00000000
--- a/common/src/test/scala/game/objectcreate/ACEDataTest.scala
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class ACEDataTest extends Specification {
- val string_ace_held = hex"17 76000000 0406900650C80480000000"
- val string_ace_dropped = hex"17 AF000000 90024113B329C5D5A2D1200005B440000000"
-
- "ACEData" should {
- "decode (held)" in {
- PacketCoding.DecodePacket(string_ace_held).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 118
- cls mustEqual ObjectClass.ace
- guid mustEqual PlanetSideGUID(3173)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(3336)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[ACEData] mustEqual true
- val ace = data.get.asInstanceOf[ACEData]
- ace.unk1 mustEqual 4
- ace.unk2 mustEqual 8
- ace.unk3 mustEqual 0
- case _ =>
- ko
- }
- }
-
- "decode (dropped)" in {
- PacketCoding.DecodePacket(string_ace_dropped).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 175
- cls mustEqual ObjectClass.ace
- guid mustEqual PlanetSideGUID(4388)
- parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
- drop.pos.coord.x mustEqual 4708.461f
- drop.pos.coord.y mustEqual 5547.539f
- drop.pos.coord.z mustEqual 72.703125f
- drop.pos.orient.x mustEqual 0f
- drop.pos.orient.y mustEqual 0f
- drop.pos.orient.z mustEqual 194.0625f
- drop.obj.isInstanceOf[ACEData] mustEqual true
- val ace = drop.obj.asInstanceOf[ACEData]
- ace.unk1 mustEqual 8
- ace.unk2 mustEqual 8
- case _ =>
- ko
- }
- }
-
- "encode (held)" in {
- val obj = ACEData(4, 8)
- val msg = ObjectCreateMessage(ObjectClass.ace, PlanetSideGUID(3173), ObjectCreateMessageParent(PlanetSideGUID(3336), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_ace_held
- }
-
- "encode (dropped)" in {
- val obj = DroppedItemData(
- PlacementData(4708.461f, 5547.539f, 72.703125f, 0f, 0f, 194.0625f),
- ACEData(8, 8)
- )
- val msg = ObjectCreateMessage(ObjectClass.ace, PlanetSideGUID(4388), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_ace_dropped
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/AegisShieldGeneratorDataTest.scala b/common/src/test/scala/game/objectcreate/AegisShieldGeneratorDataTest.scala
index 8772daf2..49d16d86 100644
--- a/common/src/test/scala/game/objectcreate/AegisShieldGeneratorDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/AegisShieldGeneratorDataTest.scala
@@ -19,15 +19,24 @@ class AegisShieldGeneratorDataTest extends Specification {
cls mustEqual ObjectClass.deployable_shield_generator
guid mustEqual PlanetSideGUID(2556)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[AegisShieldGeneratorData] mustEqual true
- val aegis = data.get.asInstanceOf[AegisShieldGeneratorData]
- aegis.deploy.pos.coord mustEqual Vector3(3571.2266f, 3278.0938f, 114.0f)
- aegis.deploy.pos.orient mustEqual Vector3(0, 0, 90)
- aegis.deploy.faction mustEqual PlanetSideEmpire.VS
- aegis.deploy.unk mustEqual 2
- aegis.health mustEqual 255
- aegis.deploy.player_guid mustEqual PlanetSideGUID(2366)
+ data match {
+ case AegisShieldGeneratorData(basic, health) =>
+ basic.pos.coord mustEqual Vector3(3571.2266f, 3278.0938f, 114.0f)
+ basic.pos.orient mustEqual Vector3.z(90.0f)
+
+ basic.data.faction mustEqual PlanetSideEmpire.VS
+ basic.data.bops mustEqual false
+ basic.data.alternate mustEqual false
+ basic.data.v1 mustEqual true
+ basic.data.v2.isDefined mustEqual false
+ basic.data.v3 mustEqual false
+ basic.data.v5.isDefined mustEqual false
+ basic.data.guid mustEqual PlanetSideGUID(2366)
+
+ health mustEqual 255
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -35,7 +44,7 @@ class AegisShieldGeneratorDataTest extends Specification {
"encode" in {
val obj = AegisShieldGeneratorData(
- CommonFieldData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3(3571.2266f, 3278.0938f, 114.0f), Vector3(0, 0, 90)),
PlanetSideEmpire.VS, 2, PlanetSideGUID(2366)
),
diff --git a/common/src/test/scala/game/objectcreate/AmmoBoxDataTest.scala b/common/src/test/scala/game/objectcreate/AmmoBoxDataTest.scala
deleted file mode 100644
index a3da9440..00000000
--- a/common/src/test/scala/game/objectcreate/AmmoBoxDataTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class AmmoBoxDataTest extends Specification {
- val string_shotgunshell_dropped = hex"17 A5000000 F9A7D0D 5E269 BED5A F114 0000596000000"
-
- "AmmoBoxData" should {
- "decode (shotgun shells, dropped)" in {
- PacketCoding.DecodePacket(string_shotgunshell_dropped).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 165
- cls mustEqual ObjectClass.shotgun_shell
- guid mustEqual PlanetSideGUID(3453)
- parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
- drop.pos.coord.x mustEqual 4684.7344f
- drop.pos.coord.y mustEqual 5547.4844f
- drop.pos.coord.z mustEqual 83.765625f
- drop.pos.orient.x mustEqual 0f
- drop.pos.orient.y mustEqual 0f
- drop.pos.orient.z mustEqual 199.6875f
- drop.obj.isInstanceOf[AmmoBoxData] mustEqual true
- val box = drop.obj.asInstanceOf[AmmoBoxData]
- box.unk mustEqual 0
- case _ =>
- ko
- }
- }
-
- "encode (shotgun shells, dropped)" in {
- val obj = DroppedItemData(
- PlacementData(4684.7344f, 5547.4844f, 83.765625f, 0f, 0f, 199.6875f),
- AmmoBoxData()
- )
- val msg = ObjectCreateMessage(ObjectClass.shotgun_shell, PlanetSideGUID(3453), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_shotgunshell_dropped
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/BoomerTriggerDataTest.scala b/common/src/test/scala/game/objectcreate/BoomerTriggerDataTest.scala
deleted file mode 100644
index db5c61d2..00000000
--- a/common/src/test/scala/game/objectcreate/BoomerTriggerDataTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class BoomerTriggerDataTest extends Specification {
- val string_boomertrigger = hex"17 76000000 58084A8100E80C00000000" //reconstructed from an inventory entry
-
- "BoomerTriggerData" should {
- "decode (held)" in {
- PacketCoding.DecodePacket(string_boomertrigger).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 118
- cls mustEqual ObjectClass.boomer_trigger
- guid mustEqual PlanetSideGUID(3600)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(4272)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[BoomerTriggerData] mustEqual true
- data.get.asInstanceOf[BoomerTriggerData].unk mustEqual 0
- case _ =>
- ko
- }
- }
-
- "encode (held)" in {
- val obj = BoomerTriggerData(0)
- val msg = ObjectCreateMessage(ObjectClass.boomer_trigger, PlanetSideGUID(3600), ObjectCreateMessageParent(PlanetSideGUID(4272), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_boomertrigger
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/CaptureFlagDataTest.scala b/common/src/test/scala/game/objectcreate/CaptureFlagDataTest.scala
index ee78c7ef..ddd0d872 100644
--- a/common/src/test/scala/game/objectcreate/CaptureFlagDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/CaptureFlagDataTest.scala
@@ -19,9 +19,8 @@ class CaptureFlagDataTest extends Specification {
cls mustEqual ObjectClass.capture_flag
guid mustEqual PlanetSideGUID(4330)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[CaptureFlagData] mustEqual true
- val flag = data.get.asInstanceOf[CaptureFlagData]
+ data.isInstanceOf[CaptureFlagData] mustEqual true
+ val flag = data.asInstanceOf[CaptureFlagData]
flag.pos.coord.x mustEqual 3912.0312f
flag.pos.coord.y mustEqual 5169.4375f
flag.pos.coord.z mustEqual 59.96875f
diff --git a/common/src/test/scala/game/objectcreate/CharacterDataTest.scala b/common/src/test/scala/game/objectcreate/CharacterDataTest.scala
index d0d14d1b..eece5121 100644
--- a/common/src/test/scala/game/objectcreate/CharacterDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/CharacterDataTest.scala
@@ -27,7 +27,7 @@ class CharacterDataTest extends Specification {
guid mustEqual PlanetSideGUID(3902)
parent.isDefined mustEqual false
data match {
- case Some(PlayerData(Some(pos), basic, char, inv, hand)) =>
+ case PlayerData(Some(pos), basic, char, inv, hand) =>
pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
pos.orient mustEqual Vector3(0f, 0f, 64.6875f)
pos.vel.isDefined mustEqual true
@@ -40,13 +40,13 @@ class CharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Male
a.app.head mustEqual 5
a.app.voice mustEqual CharacterVoice.Voice5
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Reinforced
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 30777081L
a.unk7 mustEqual 1
@@ -63,7 +63,7 @@ class CharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 316554L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -87,12 +87,12 @@ class CharacterDataTest extends Specification {
char.command_rank mustEqual 5
char.implant_effects.length mustEqual 1
char.implant_effects.head mustEqual ImplantEffects.NoEffects
- char.cosmetics.isDefined mustEqual true
- char.cosmetics.get.no_helmet mustEqual true
- char.cosmetics.get.beret mustEqual true
- char.cosmetics.get.sunglasses mustEqual true
- char.cosmetics.get.earpiece mustEqual true
- char.cosmetics.get.brimmed_cap mustEqual false
+ char.cosmetics match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret, PersonalStyle.Sunglasses, PersonalStyle.Earpiece)
+ case None =>
+ ko
+ }
char.unk mustEqual 7
//short test of inventory items
inv.isDefined mustEqual true
@@ -149,9 +149,9 @@ class CharacterDataTest extends Specification {
len mustEqual 1795
cls mustEqual ObjectClass.avatar
guid mustEqual PlanetSideGUID(3902)
- parent mustEqual Some(ObjectCreateMessageParent(PlanetSideGUID(1234), 0))
+ parent.contains(ObjectCreateMessageParent(PlanetSideGUID(1234), 0)) mustEqual true
data match {
- case Some(PlayerData(None, basic, char, inv, hand)) =>
+ case PlayerData(None, basic, _, _, _) =>
basic match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app.name mustEqual "ScrawnyRonnie"
@@ -159,13 +159,13 @@ class CharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Male
a.app.head mustEqual 5
a.app.voice mustEqual CharacterVoice.Voice5
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Reinforced
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 192L
a.unk7 mustEqual 0
@@ -182,7 +182,7 @@ class CharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 26L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -216,7 +216,7 @@ class CharacterDataTest extends Specification {
guid mustEqual PlanetSideGUID(3380)
parent.isDefined mustEqual false
data match {
- case Some(PlayerData(Some(pos), basic, char, None, hand)) =>
+ case PlayerData(Some(pos), basic, char, None, hand) =>
pos.coord mustEqual Vector3(4629.8906f, 6316.4453f, 54.734375f)
pos.orient mustEqual Vector3(0, 0, 126.5625f)
pos.vel.isDefined mustEqual false
@@ -228,13 +228,13 @@ class CharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Male
a.app.head mustEqual 10
a.app.voice mustEqual CharacterVoice.Voice2
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.MAX
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 1
a.unk6 mustEqual 0L
a.unk7 mustEqual 0
@@ -251,7 +251,7 @@ class CharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 529687L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -275,12 +275,12 @@ class CharacterDataTest extends Specification {
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
char.command_rank mustEqual 2
char.implant_effects.isEmpty mustEqual true
- char.cosmetics.isDefined mustEqual true
- char.cosmetics.get.no_helmet mustEqual true
- char.cosmetics.get.beret mustEqual true
- char.cosmetics.get.sunglasses mustEqual true
- char.cosmetics.get.earpiece mustEqual true
- char.cosmetics.get.brimmed_cap mustEqual false
+ char.cosmetics match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret, PersonalStyle.Sunglasses, PersonalStyle.Earpiece)
+ case None =>
+ ko
+ }
char.unk mustEqual 1
hand mustEqual DrawnSlot.Pistol1
@@ -306,14 +306,18 @@ class CharacterDataTest extends Specification {
5,
CharacterVoice.Voice5
),
- false,
- false,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Reinforced,
- None,
- 0,
0,
30777081L,
1,
@@ -341,7 +345,7 @@ class CharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
a, b,
RibbonBars(
MeritCommendation.MarkovVeteran,
@@ -359,11 +363,11 @@ class CharacterDataTest extends Specification {
Some(Cosmetics(true, true, true, true, false))
)
val inv = InventoryData(
- InventoryItemData(ObjectClass.plasma_grenade, PlanetSideGUID(3662), 0, WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.bank, PlanetSideGUID(3908), 1, WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.mini_chaingun, PlanetSideGUID(4164), 2, WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.phoenix, PlanetSideGUID(3603), 3, WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.chainblade, PlanetSideGUID(4088), 4, WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, AmmoBoxData())) ::
+ InventoryItemData(ObjectClass.plasma_grenade, PlanetSideGUID(3662), 0, WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.bank, PlanetSideGUID(3908), 1, WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.mini_chaingun, PlanetSideGUID(4164), 2, WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.phoenix, PlanetSideGUID(3603), 3, WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.chainblade, PlanetSideGUID(4088), 4, WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, CommonFieldData()(false))) ::
Nil
)
val obj = PlayerData(pos, app, char, inv, DrawnSlot.Rifle1)
@@ -382,14 +386,18 @@ class CharacterDataTest extends Specification {
5,
CharacterVoice.Voice5
),
- false,
- false,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Reinforced,
- None,
- 0,
0,
192L,
0,
@@ -417,7 +425,7 @@ class CharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
a, b,
RibbonBars(
MeritCommendation.MarkovVeteran,
@@ -434,11 +442,11 @@ class CharacterDataTest extends Specification {
Some(Cosmetics(true, true, true, true, false))
)
val inv = InventoryData(
- InventoryItemData(ObjectClass.plasma_grenade, PlanetSideGUID(3662), 0, WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.bank, PlanetSideGUID(3908), 1, WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.mini_chaingun, PlanetSideGUID(4164), 2, WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.phoenix, PlanetSideGUID(3603), 3, WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.chainblade, PlanetSideGUID(4088), 4, WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, AmmoBoxData())) ::
+ InventoryItemData(ObjectClass.plasma_grenade, PlanetSideGUID(3662), 0, WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.bank, PlanetSideGUID(3908), 1, WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.mini_chaingun, PlanetSideGUID(4164), 2, WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.phoenix, PlanetSideGUID(3603), 3, WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, CommonFieldData()(false))) ::
+ InventoryItemData(ObjectClass.chainblade, PlanetSideGUID(4088), 4, WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, CommonFieldData()(false))) ::
Nil
)
val obj = PlayerData(app, char, inv, DrawnSlot.Rifle1)
@@ -461,14 +469,18 @@ class CharacterDataTest extends Specification {
10,
CharacterVoice.Voice2
),
- false,
- true,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.VS,
+ false,
+ true,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.MAX,
- None,
- 0,
1,
0L,
0,
@@ -496,7 +508,7 @@ class CharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
a, b,
RibbonBars(
MeritCommendation.Jacking2,
diff --git a/common/src/test/scala/game/objectcreate/CommandDetonaterDataTest.scala b/common/src/test/scala/game/objectcreate/CommandDetonaterDataTest.scala
deleted file mode 100644
index c01dece3..00000000
--- a/common/src/test/scala/game/objectcreate/CommandDetonaterDataTest.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class CommandDetonaterDataTest extends Specification {
- val string_detonater_held = hex"17 76000000 1A886A8421080400000000"
- val string_detonater_dropped = hex"17 AF000000 EA8620ED1549B4B6A741500001B000000000"
-
- "CommandDetonaterData" should {
- "decode (held)" in {
- PacketCoding.DecodePacket(string_detonater_held).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 118
- cls mustEqual ObjectClass.command_detonater
- guid mustEqual PlanetSideGUID(4162)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(4149)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[CommandDetonaterData] mustEqual true
- val cud = data.get.asInstanceOf[CommandDetonaterData]
- cud.unk1 mustEqual 4
- cud.unk2 mustEqual 0
- case _ =>
- ko
- }
- }
-
- "decode (dropped)" in {
- PacketCoding.DecodePacket(string_detonater_dropped).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 175
- cls mustEqual ObjectClass.command_detonater
- guid mustEqual PlanetSideGUID(3682)
- parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
- drop.pos.coord.x mustEqual 4777.633f
- drop.pos.coord.y mustEqual 5485.4062f
- drop.pos.coord.z mustEqual 85.8125f
- drop.pos.orient.x mustEqual 0f
- drop.pos.orient.y mustEqual 0f
- drop.pos.orient.z mustEqual 14.0625f
- drop.obj.isInstanceOf[CommandDetonaterData] mustEqual true
- case _ =>
- ko
- }
- }
-
- "encode (held)" in {
- val obj = CommandDetonaterData(4)
- val msg = ObjectCreateMessage(ObjectClass.command_detonater, PlanetSideGUID(4162), ObjectCreateMessageParent(PlanetSideGUID(4149), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_detonater_held
- }
-
- "encode (dropped)" in {
- val obj = DroppedItemData(
- PlacementData(4777.633f, 5485.4062f, 85.8125f, 0f, 0f, 14.0625f),
- CommandDetonaterData()
- )
- val msg = ObjectCreateMessage(ObjectClass.command_detonater, PlanetSideGUID(3682), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_detonater_dropped
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/CommonFieldDataTest.scala b/common/src/test/scala/game/objectcreate/CommonFieldDataTest.scala
index 3ce92333..57ba9438 100644
--- a/common/src/test/scala/game/objectcreate/CommonFieldDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/CommonFieldDataTest.scala
@@ -1,16 +1,123 @@
-// Copyright (c) 2017 PSForever
+// Copyright (c) 2019 PSForever
package game.objectcreate
-import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.PacketCoding
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
import net.psforever.types.PlanetSideEmpire
-import org.specs2.mutable._
+import org.specs2.mutable.Specification
+import scodec.bits._
-class CommonFieldDataTest extends Specification {
- "CommonFieldData" should {
- "construct" in {
- CommonFieldData(PlacementData(0f, 0f, 0f), PlanetSideEmpire.NC, true, 5) mustEqual
- CommonFieldData(PlacementData(0f, 0f, 0f), PlanetSideEmpire.NC, false, true, 5, false, PlanetSideGUID(0))
+object CommonFieldDataTest extends Specification {
+ val string_shotgunshell_dropped = hex"17 A5000000 F9A7D0D 5E269 BED5A F114 0000596000000"
+ val string_implant_interface = hex"17 6C000000 01014C93304818000000"
+ val string_order_terminala = hex"17 A5000000 B2AF30EACF1889F7A3D1200007D2000000"
+
+ "AmmoBoxData" should {
+ "decode (shotgun shells, dropped)" in {
+ PacketCoding.DecodePacket(string_shotgunshell_dropped).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 165
+ cls mustEqual ObjectClass.shotgun_shell
+ guid mustEqual PlanetSideGUID(3453)
+ parent.isDefined mustEqual false
+ data.isInstanceOf[DroppedItemData[_]] mustEqual true
+ val drop = data.asInstanceOf[DroppedItemData[_]]
+ drop.pos.coord.x mustEqual 4684.7344f
+ drop.pos.coord.y mustEqual 5547.4844f
+ drop.pos.coord.z mustEqual 83.765625f
+ drop.pos.orient.x mustEqual 0f
+ drop.pos.orient.y mustEqual 0f
+ drop.pos.orient.z mustEqual 199.6875f
+ drop.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode (shotgun shells, dropped)" in {
+ val obj = DroppedItemData(
+ PlacementData(4684.7344f, 5547.4844f, 83.765625f, 0f, 0f, 199.6875f),
+ CommonFieldData()(false)
+ )
+ val msg = ObjectCreateMessage(ObjectClass.shotgun_shell, PlanetSideGUID(3453), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_shotgunshell_dropped
+ }
+ }
+
+
+ "TerminalData" should {
+ "decode (implant interface)" in {
+ PacketCoding.DecodePacket(string_implant_interface).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 108
+ cls mustEqual 0x199
+ guid mustEqual PlanetSideGUID(1075)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(514)
+ parent.get.slot mustEqual 1
+ data.isInstanceOf[CommonFieldData] mustEqual true
+ case _ =>
+ ko
+ }
+ }
+
+ "decode (order terminal a)" in {
+ PacketCoding.DecodePacket(string_order_terminala).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 165
+ cls mustEqual ObjectClass.order_terminala
+ guid mustEqual PlanetSideGUID(3827)
+ parent.isDefined mustEqual false
+ data.isInstanceOf[DroppedItemData[_]] mustEqual true
+ val drop = data.asInstanceOf[DroppedItemData[_]]
+ drop.pos.coord.x mustEqual 4579.3438f
+ drop.pos.coord.y mustEqual 5615.0703f
+ drop.pos.coord.z mustEqual 72.953125f
+ drop.pos.orient.x mustEqual 0f
+ drop.pos.orient.y mustEqual 0f
+ drop.pos.orient.z mustEqual 98.4375f
+ drop.obj.isInstanceOf[CommonFieldData] mustEqual true
+ drop.obj.asInstanceOf[CommonFieldData].faction mustEqual PlanetSideEmpire.NC
+ case _ =>
+ ko
+ }
+ }
+
+ "encode (implant interface)" in {
+ val obj = CommonFieldData(PlanetSideEmpire.VS)(false)
+ val msg = ObjectCreateMessage(0x199, PlanetSideGUID(1075), ObjectCreateMessageParent(PlanetSideGUID(514), 1), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_implant_interface
+ }
+
+ "encode (order terminal a)" in {
+ val obj = DroppedItemData(
+ PlacementData(4579.3438f, 5615.0703f, 72.953125f, 0f, 0f, 98.4375f),
+ CommonFieldData(PlanetSideEmpire.NC)(false)
+ )
+ val msg = ObjectCreateMessage(ObjectClass.order_terminala, PlanetSideGUID(3827), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_order_terminala
+ }
+
+ "InternalSlot" in {
+ TerminalData(ObjectClass.order_terminala, PlanetSideGUID(1), 1, CommonFieldData(PlanetSideEmpire.NC)(false)) mustEqual
+ InternalSlot(ObjectClass.order_terminala, PlanetSideGUID(1), 1, CommonFieldData(PlanetSideEmpire.NC)(false))
}
}
}
diff --git a/common/src/test/scala/game/objectcreate/CommonFieldDataWithPlacementTest.scala b/common/src/test/scala/game/objectcreate/CommonFieldDataWithPlacementTest.scala
new file mode 100644
index 00000000..65737f1e
--- /dev/null
+++ b/common/src/test/scala/game/objectcreate/CommonFieldDataWithPlacementTest.scala
@@ -0,0 +1,58 @@
+// Copyright (c) 2017 PSForever
+package game.objectcreate
+
+import net.psforever.packet.PacketCoding
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
+import net.psforever.packet.game.objectcreate._
+import net.psforever.types.{PlanetSideEmpire, Vector3}
+import org.specs2.mutable._
+import scodec.bits._
+
+class CommonFieldDataWithPlacementTest extends Specification {
+ val string_boomer = hex"17 A5000000 CA0000F1630938D5A8F1400003F0031100"
+
+ "Boomer" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_boomer).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 165
+ cls mustEqual ObjectClass.boomer
+ guid mustEqual PlanetSideGUID(3840)
+ parent.isDefined mustEqual false
+ data match {
+ case CommonFieldDataWithPlacement(pos, com) =>
+ pos.coord mustEqual Vector3(4704.172f, 5546.4375f, 82.234375f)
+ pos.orient mustEqual Vector3.z(272.8125f)
+ com match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.TR
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(8290)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = CommonFieldDataWithPlacement(
+ PlacementData(Vector3(4704.172f, 5546.4375f, 82.234375f), Vector3.z(272.8125f)),
+ CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, Some(false), None, PlanetSideGUID(8290))
+ )
+ val msg = ObjectCreateMessage(ObjectClass.boomer, PlanetSideGUID(3840), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_boomer
+ }
+ }
+}
diff --git a/common/src/test/scala/game/objectcreate/CommonTerminalDataTest.scala b/common/src/test/scala/game/objectcreate/CommonTerminalDataTest.scala
deleted file mode 100644
index 2e4a4d70..00000000
--- a/common/src/test/scala/game/objectcreate/CommonTerminalDataTest.scala
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import net.psforever.types.PlanetSideEmpire
-import org.specs2.mutable._
-import scodec.bits._
-
-class CommonTerminalDataTest extends Specification {
- val string_implant_interface = hex"17 6C000000 01014C93304818000000"
- val string_order_terminala = hex"17 A5000000 B2AF30EACF1889F7A3D1200007D2000000"
-
- "CommonTerminalData" should {
- "decode (implant interface)" in {
- PacketCoding.DecodePacket(string_implant_interface).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 108
- cls mustEqual 0x199
- guid mustEqual PlanetSideGUID(1075)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(514)
- parent.get.slot mustEqual 1
- data.isDefined mustEqual true
- data.get.isInstanceOf[CommonTerminalData] mustEqual true
- data.get.asInstanceOf[CommonTerminalData].faction mustEqual PlanetSideEmpire.VS
- case _ =>
- ko
- }
- }
-
- "decode (order terminal a)" in {
- PacketCoding.DecodePacket(string_order_terminala).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 165
- cls mustEqual ObjectClass.order_terminala
- guid mustEqual PlanetSideGUID(3827)
- parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
- drop.pos.coord.x mustEqual 4579.3438f
- drop.pos.coord.y mustEqual 5615.0703f
- drop.pos.coord.z mustEqual 72.953125f
- drop.pos.orient.x mustEqual 0f
- drop.pos.orient.y mustEqual 0f
- drop.pos.orient.z mustEqual 98.4375f
- drop.obj.isInstanceOf[CommonTerminalData] mustEqual true
- val term = drop.obj.asInstanceOf[CommonTerminalData]
- term.faction mustEqual PlanetSideEmpire.NC
- term.unk mustEqual 0
- case _ =>
- ko
- }
- }
-
- "encode (implant interface)" in {
- val obj = CommonTerminalData(PlanetSideEmpire.VS)
- val msg = ObjectCreateMessage(0x199, PlanetSideGUID(1075), ObjectCreateMessageParent(PlanetSideGUID(514), 1), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_implant_interface
- }
-
- "encode (order terminal a)" in {
- val obj = DroppedItemData(
- PlacementData(4579.3438f, 5615.0703f, 72.953125f, 0f, 0f, 98.4375f),
- CommonTerminalData(PlanetSideEmpire.NC)
- )
- val msg = ObjectCreateMessage(ObjectClass.order_terminala, PlanetSideGUID(3827), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_order_terminala
- }
-
- "InternalSlot" in {
- CommonTerminalData(ObjectClass.order_terminala, PlanetSideGUID(1), 1, CommonTerminalData(PlanetSideEmpire.NC)) mustEqual
- InternalSlot(ObjectClass.order_terminala, PlanetSideGUID(1), 1, CommonTerminalData(PlanetSideEmpire.NC))
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/ContainedTelepadDeployableDataTest.scala b/common/src/test/scala/game/objectcreate/ContainedTelepadDeployableDataTest.scala
deleted file mode 100644
index f32b7c26..00000000
--- a/common/src/test/scala/game/objectcreate/ContainedTelepadDeployableDataTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class ContainedTelepadDeployableDataTest extends Specification {
- val string = hex"178f0000004080f42b00182cb0202000100000"
-
- "ContainedTelepadDeployableData" should {
- "decode" in {
- PacketCoding.DecodePacket(string).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 143
- cls mustEqual 744
- guid mustEqual PlanetSideGUID(432)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(385)
- parent.get.slot mustEqual 2
- data.isDefined mustEqual true
- data.get.isInstanceOf[ContainedTelepadDeployableData] mustEqual true
- data.get.asInstanceOf[ContainedTelepadDeployableData].unk mustEqual 101
- data.get.asInstanceOf[ContainedTelepadDeployableData].router_guid mustEqual PlanetSideGUID(385)
- case _ =>
- ko
- }
- }
- "encode" in {
- val obj = ContainedTelepadDeployableData(101, PlanetSideGUID(385))
- val msg = ObjectCreateMessage(744, PlanetSideGUID(432), ObjectCreateMessageParent(PlanetSideGUID(385), 2), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/HandheldDataTest.scala b/common/src/test/scala/game/objectcreate/HandheldDataTest.scala
new file mode 100644
index 00000000..94078f9a
--- /dev/null
+++ b/common/src/test/scala/game/objectcreate/HandheldDataTest.scala
@@ -0,0 +1,249 @@
+// Copyright (c) 2017 PSForever
+package game.objectcreate
+
+import net.psforever.packet.PacketCoding
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
+import net.psforever.packet.game.objectcreate._
+import net.psforever.types.{PlanetSideEmpire, Vector3}
+import org.specs2.mutable._
+import scodec.bits._
+
+class HandheldDataTest extends Specification {
+ val string_ace_held = hex"17 76000000 0406900650C80480000000"
+ val string_ace_dropped = hex"17 AF000000 90024113B329C5D5A2D1200005B440000000"
+
+ "ACE" should {
+ "decode (held)" in {
+ PacketCoding.DecodePacket(string_ace_held).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 118
+ cls mustEqual ObjectClass.ace
+ guid mustEqual PlanetSideGUID(3173)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(3336)
+ parent.get.slot mustEqual 0
+ data match {
+ case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
+ faction mustEqual PlanetSideEmpire.NC
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "decode (dropped)" in {
+ PacketCoding.DecodePacket(string_ace_dropped).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 175
+ cls mustEqual ObjectClass.ace
+ guid mustEqual PlanetSideGUID(4388)
+ parent.isDefined mustEqual false
+ data.isInstanceOf[DroppedItemData[_]] mustEqual true
+ data match {
+ case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid))) =>
+ pos.coord mustEqual Vector3(4708.461f, 5547.539f, 72.703125f)
+ pos.orient mustEqual Vector3.z(194.0625f)
+
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode (held)" in {
+ val obj = HandheldData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)))
+ val msg = ObjectCreateMessage(ObjectClass.ace, PlanetSideGUID(3173), ObjectCreateMessageParent(PlanetSideGUID(3336), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_ace_held
+ }
+
+ "encode (dropped)" in {
+ val obj = DroppedItemData(
+ PlacementData(4708.461f, 5547.539f, 72.703125f, 0f, 0f, 194.0625f),
+ HandheldData(CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)))
+ )
+ val msg = ObjectCreateMessage(ObjectClass.ace, PlanetSideGUID(4388), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_ace_dropped
+ }
+ }
+
+ val string_telepad = hex"17 86000000 5700 f3a a201 80 0302020000000"
+
+ "Telepad" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_telepad).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 134
+ cls mustEqual ObjectClass.router_telepad
+ guid mustEqual PlanetSideGUID(418)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(430)
+ parent.get.slot mustEqual 0
+ data match {
+ case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
+ faction mustEqual PlanetSideEmpire.TR
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.contains(385) mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = HandheldData(CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, None, Some(385), PlanetSideGUID(0)))
+ val msg = ObjectCreateMessage(ObjectClass.router_telepad, PlanetSideGUID(418), ObjectCreateMessageParent(PlanetSideGUID(430), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_telepad
+ }
+ }
+
+ val string_boomertrigger = hex"17 76000000 58084A8100E80C00000000" //reconstructed from an inventory entry
+
+ "Boomer Trigger" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_boomertrigger).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 118
+ cls mustEqual ObjectClass.boomer_trigger
+ guid mustEqual PlanetSideGUID(3600)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(4272)
+ parent.get.slot mustEqual 0
+ data match {
+ case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = HandheldData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)))
+ val msg = ObjectCreateMessage(ObjectClass.boomer_trigger, PlanetSideGUID(3600), ObjectCreateMessageParent(PlanetSideGUID(4272), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_boomertrigger
+ }
+ }
+
+ val string_detonater_held = hex"17 76000000 1A886A8421080400000000"
+ val string_detonater_dropped = hex"17 AF000000 EA8620ED1549B4B6A741500001B000000000"
+
+ "Command Detonater" should {
+ "decode (held)" in {
+ PacketCoding.DecodePacket(string_detonater_held).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 118
+ cls mustEqual ObjectClass.command_detonater
+ guid mustEqual PlanetSideGUID(4162)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(4149)
+ parent.get.slot mustEqual 0
+ data match {
+ case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
+ faction mustEqual PlanetSideEmpire.NC
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "decode (dropped)" in {
+ PacketCoding.DecodePacket(string_detonater_dropped).require match {
+ case ObjectCreateMessage(len, cls, guid, parent, data) =>
+ len mustEqual 175
+ cls mustEqual ObjectClass.command_detonater
+ guid mustEqual PlanetSideGUID(3682)
+ parent.isDefined mustEqual false
+ data match {
+ case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid))) =>
+ pos.coord mustEqual Vector3(4777.633f, 5485.4062f, 85.8125f)
+ pos.orient mustEqual Vector3.z(14.0625f)
+
+ faction mustEqual PlanetSideEmpire.TR
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode (held)" in {
+ val obj = HandheldData(CommonFieldData(PlanetSideEmpire.NC, false, false, false, None, false, None, None, PlanetSideGUID(0)))
+ val msg = ObjectCreateMessage(ObjectClass.command_detonater, PlanetSideGUID(4162), ObjectCreateMessageParent(PlanetSideGUID(4149), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_detonater_held
+ }
+
+ "encode (dropped)" in {
+ val obj = DroppedItemData(
+ PlacementData(4777.633f, 5485.4062f, 85.8125f, 0f, 0f, 14.0625f),
+ HandheldData(CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, None, None, PlanetSideGUID(0)))
+ )
+ val msg = ObjectCreateMessage(ObjectClass.command_detonater, PlanetSideGUID(3682), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ pkt mustEqual string_detonater_dropped
+ }
+ }
+}
diff --git a/common/src/test/scala/game/objectcreate/LockerContainerDataTest.scala b/common/src/test/scala/game/objectcreate/LockerContainerDataTest.scala
index 2c81aea9..f960c318 100644
--- a/common/src/test/scala/game/objectcreate/LockerContainerDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/LockerContainerDataTest.scala
@@ -4,6 +4,7 @@ package game.objectcreate
import net.psforever.packet.PacketCoding
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import org.specs2.mutable._
import scodec.bits._
@@ -18,36 +19,43 @@ class LockerContainerDataTest extends Specification {
cls mustEqual ObjectClass.locker_container
guid mustEqual PlanetSideGUID(3148)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[LockerContainerData] mustEqual true
- val locker = data.get.asInstanceOf[LockerContainerData]
- val contents = locker.inventory.contents
- contents.size mustEqual 3
- //0
- contents.head.objectClass mustEqual ObjectClass.nano_dispenser
- contents.head.guid mustEqual PlanetSideGUID(2935)
- contents.head.parentSlot mustEqual 0
- contents.head.obj.isInstanceOf[WeaponData] mustEqual true
- val dispenser = contents.head.obj.asInstanceOf[WeaponData]
- dispenser.unk1 mustEqual 0x6
- dispenser.unk2 mustEqual 0x0
- dispenser.ammo.head.objectClass mustEqual ObjectClass.armor_canister
- dispenser.ammo.head.guid mustEqual PlanetSideGUID(3426)
- dispenser.ammo.head.parentSlot mustEqual 0
- dispenser.ammo.head.obj.isInstanceOf[AmmoBoxData] mustEqual true
- dispenser.ammo.head.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0
- //1
- contents(1).objectClass mustEqual ObjectClass.armor_canister
- contents(1).guid mustEqual PlanetSideGUID(4090)
- contents(1).parentSlot mustEqual 45
- contents(1).obj.isInstanceOf[AmmoBoxData] mustEqual true
- contents(1).obj.asInstanceOf[AmmoBoxData].unk mustEqual 0
- //2
- contents(2).objectClass mustEqual ObjectClass.armor_canister
- contents(2).guid mustEqual PlanetSideGUID(3326)
- contents(2).parentSlot mustEqual 78
- contents(2).obj.isInstanceOf[AmmoBoxData] mustEqual true
- contents(2).obj.asInstanceOf[AmmoBoxData].unk mustEqual 0
+ data.isInstanceOf[LockerContainerData] mustEqual true
+ val locker = data.asInstanceOf[LockerContainerData]
+ locker.inventory match {
+ case Some(InventoryData(contents)) =>
+ contents.size mustEqual 3
+ //0
+ contents.head.objectClass mustEqual ObjectClass.nano_dispenser
+ contents.head.guid mustEqual PlanetSideGUID(2935)
+ contents.head.parentSlot mustEqual 0
+ contents.head.obj match {
+ case WeaponData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), _, _, _) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ //1
+ contents(1).objectClass mustEqual ObjectClass.armor_canister
+ contents(1).guid mustEqual PlanetSideGUID(4090)
+ contents(1).parentSlot mustEqual 45
+ contents(1).obj.isInstanceOf[CommonFieldData] mustEqual true
+ //2
+ contents(2).objectClass mustEqual ObjectClass.armor_canister
+ contents(2).guid mustEqual PlanetSideGUID(3326)
+ contents(2).parentSlot mustEqual 78
+ contents(2).obj.isInstanceOf[CommonFieldData] mustEqual true
+ case None =>
+ ko
+ }
+
case _ =>
ko
}
@@ -55,12 +63,17 @@ class LockerContainerDataTest extends Specification {
"encode" in {
val obj = LockerContainerData(
- InventoryData(
- InventoryItemData(ObjectClass.nano_dispenser, PlanetSideGUID(2935), 0, WeaponData(0x6, 0x0, ObjectClass.armor_canister, PlanetSideGUID(3426), 0, AmmoBoxData())) ::
- InventoryItemData(ObjectClass.armor_canister, PlanetSideGUID(4090), 45, AmmoBoxData()) ::
- InventoryItemData(ObjectClass.armor_canister, PlanetSideGUID(3326), 78, AmmoBoxData()) ::
- Nil
- )
+ InventoryData(List(
+ InventoryItemData(ObjectClass.nano_dispenser, PlanetSideGUID(2935), 0,
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.armor_canister, PlanetSideGUID(3426), 0, CommonFieldData()(false)))
+ )
+ ),
+ InventoryItemData(ObjectClass.armor_canister, PlanetSideGUID(4090), 45, CommonFieldData()(false)),
+ InventoryItemData(ObjectClass.armor_canister, PlanetSideGUID(3326), 78, CommonFieldData()(false))
+ ))
)
val msg = ObjectCreateMessage(ObjectClass.locker_container, PlanetSideGUID(3148), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreate/OneMannedFieldTurretDataTest.scala b/common/src/test/scala/game/objectcreate/OneMannedFieldTurretDataTest.scala
index e7815d72..b94884ab 100644
--- a/common/src/test/scala/game/objectcreate/OneMannedFieldTurretDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/OneMannedFieldTurretDataTest.scala
@@ -19,31 +19,62 @@ class OneMannedFieldTurretDataTest extends Specification {
cls mustEqual ObjectClass.portable_manned_turret_vs
guid mustEqual PlanetSideGUID(2916)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[OneMannedFieldTurretData] mustEqual true
- val omft = data.get.asInstanceOf[OneMannedFieldTurretData]
- omft.deploy.pos.coord mustEqual Vector3(3567.1406f, 2988.0078f, 71.84375f)
- omft.deploy.pos.orient mustEqual Vector3(0, 0, 185.625f)
- omft.deploy.faction mustEqual PlanetSideEmpire.VS
- omft.deploy.unk1 mustEqual 2
- omft.deploy.owner_guid mustEqual PlanetSideGUID(2502)
- omft.health mustEqual 255
- omft.internals.isDefined mustEqual true
- val internals = omft.internals.get.contents
- internals.head.objectClass mustEqual ObjectClass.energy_gun_vs
- internals.head.guid mustEqual PlanetSideGUID(2615)
- internals.head.parentSlot mustEqual 1
- internals.head.obj.isInstanceOf[WeaponData] mustEqual true
- val wep = internals.head.obj.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 0x6
- wep.unk2 mustEqual 0x8
- wep.fire_mode mustEqual 0
- val ammo = wep.ammo.head
- ammo.objectClass mustEqual ObjectClass.energy_gun_ammo
- ammo.guid mustEqual PlanetSideGUID(2510)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 8
+ data match {
+ case OneMannedFieldTurretData(CommonFieldDataWithPlacement(pos, deploy), health, Some(InventoryData(inv))) =>
+ pos.coord mustEqual Vector3(3567.1406f, 2988.0078f, 71.84375f)
+ pos.orient mustEqual Vector3.z(185.625f)
+ deploy.faction mustEqual PlanetSideEmpire.VS
+ deploy.bops mustEqual false
+ deploy.alternate mustEqual false
+ deploy.v1 mustEqual true
+ deploy.v2.isEmpty mustEqual true
+ deploy.v3 mustEqual false
+ deploy.v4.contains(false) mustEqual true
+ deploy.v5.isEmpty mustEqual true
+ deploy.guid mustEqual PlanetSideGUID(2502)
+
+ health mustEqual 255
+
+ inv.head.objectClass mustEqual ObjectClass.energy_gun_vs
+ inv.head.guid mustEqual PlanetSideGUID(2615)
+ inv.head.parentSlot mustEqual 1
+ inv.head.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.energy_gun_ammo
+ ammo.guid mustEqual PlanetSideGUID(2510)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -51,52 +82,26 @@ class OneMannedFieldTurretDataTest extends Specification {
"encode (orion)" in {
val obj = OneMannedFieldTurretData(
- SmallDeployableData(
- PlacementData(Vector3(3567.1406f, 2988.0078f, 71.84375f), Vector3(0, 0, 185.625f)),
- PlanetSideEmpire.VS, false, false, 2, false, false, PlanetSideGUID(2502)
+ CommonFieldDataWithPlacement(
+ PlacementData(Vector3(3567.1406f, 2988.0078f, 71.84375f), Vector3.z(185.625f)),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(2502))
),
255,
- InventoryData(List(OneMannedFieldTurretData.orion(PlanetSideGUID(2615), 0x6, 0x8, PlanetSideGUID(2510), 8)))
+ InventoryData(List(
+ InternalSlot(ObjectClass.energy_gun_vs, PlanetSideGUID(2615), 1,
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.energy_gun_ammo, PlanetSideGUID(2510), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
+ )
+ )
+ )
+ ))
)
val msg = ObjectCreateMessage(ObjectClass.portable_manned_turret_vs, PlanetSideGUID(2916), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_orion
}
-
- "avenger" in {
- OneMannedFieldTurretData.avenger(PlanetSideGUID(1), 2, 3, PlanetSideGUID(4), 5) mustEqual
- InternalSlot(ObjectClass.energy_gun_tr, PlanetSideGUID(1), 1,
- WeaponData(2, 3, ObjectClass.energy_gun_ammo, PlanetSideGUID(4), 0,
- AmmoBoxData(5)
- )
- )
- }
-
- "generic" in {
- OneMannedFieldTurretData.generic(PlanetSideGUID(1), 2, 3, PlanetSideGUID(4), 5) mustEqual
- InternalSlot(ObjectClass.energy_gun, PlanetSideGUID(1), 1,
- WeaponData(2, 3, ObjectClass.energy_gun_ammo, PlanetSideGUID(4), 0,
- AmmoBoxData(5)
- )
- )
- }
-
- "orion" in {
- OneMannedFieldTurretData.orion(PlanetSideGUID(1), 2, 3, PlanetSideGUID(4), 5) mustEqual
- InternalSlot(ObjectClass.energy_gun_vs, PlanetSideGUID(1), 1,
- WeaponData(2, 3, ObjectClass.energy_gun_ammo, PlanetSideGUID(4), 0,
- AmmoBoxData(5)
- )
- )
- }
-
- "osprey" in {
- OneMannedFieldTurretData.osprey(PlanetSideGUID(1), 2, 3, PlanetSideGUID(4), 5) mustEqual
- InternalSlot(ObjectClass.energy_gun_nc, PlanetSideGUID(1), 1,
- WeaponData(2, 3, ObjectClass.energy_gun_ammo, PlanetSideGUID(4), 0,
- AmmoBoxData(5)
- )
- )
- }
}
}
diff --git a/common/src/test/scala/game/objectcreate/REKDataTest.scala b/common/src/test/scala/game/objectcreate/REKDataTest.scala
index 3de8dc63..328c10db 100644
--- a/common/src/test/scala/game/objectcreate/REKDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/REKDataTest.scala
@@ -4,6 +4,7 @@ package game.objectcreate
import net.psforever.packet.PacketCoding
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.{PlanetSideEmpire, Vector3}
import org.specs2.mutable._
import scodec.bits._
@@ -21,12 +22,21 @@ class REKDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(4174)
parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[REKData] mustEqual true
- val rek = data.get.asInstanceOf[REKData]
- rek.unk1 mustEqual 0
- rek.unk2 mustEqual 8
- rek.unk3 mustEqual 0
+ data match {
+ case REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk) =>
+ faction mustEqual PlanetSideEmpire.TR
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ unk mustEqual 0
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -39,27 +49,32 @@ class REKDataTest extends Specification {
cls mustEqual ObjectClass.remote_electronics_kit
guid mustEqual PlanetSideGUID(4355)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val dropped = data.get.asInstanceOf[DroppedItemData[_]]
- dropped.pos.coord.x mustEqual 4675.039f
- dropped.pos.coord.y mustEqual 5506.953f
- dropped.pos.coord.z mustEqual 72.703125f
- dropped.pos.orient.x mustEqual 0f
- dropped.pos.orient.y mustEqual 0f
- dropped.pos.orient.z mustEqual 230.625f
- dropped.obj.isInstanceOf[REKData] mustEqual true
- val rek = dropped.obj.asInstanceOf[REKData]
- rek.unk1 mustEqual 8
- rek.unk2 mustEqual 0
- rek.unk3 mustEqual 3
+ data match {
+ case DroppedItemData(pos, REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk)) =>
+ pos.coord mustEqual Vector3(4675.039f, 5506.953f, 72.703125f)
+ pos.orient mustEqual Vector3.z(230.625f)
+
+ faction mustEqual PlanetSideEmpire.VS
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+
+ unk mustEqual 3
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
"encode (held)" in {
- val obj = REKData(0, 8)
+ val obj = REKData(CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
val msg = ObjectCreateMessage(ObjectClass.remote_electronics_kit, PlanetSideGUID(3893), ObjectCreateMessageParent(PlanetSideGUID(4174), 0), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_rek_held
@@ -68,7 +83,7 @@ class REKDataTest extends Specification {
"encode (dropped)" in {
val obj = DroppedItemData(
PlacementData(4675.039f, 5506.953f, 72.703125f, 0f, 0f, 230.625f),
- REKData(8, 0, 3)
+ REKData(CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)), 3)
)
val msg = ObjectCreateMessage(ObjectClass.remote_electronics_kit, PlanetSideGUID(4355), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreate/SmallDeployableDataTest.scala b/common/src/test/scala/game/objectcreate/SmallDeployableDataTest.scala
deleted file mode 100644
index 6ce53364..00000000
--- a/common/src/test/scala/game/objectcreate/SmallDeployableDataTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet.PacketCoding
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate._
-import net.psforever.types.{PlanetSideEmpire, Vector3}
-import org.specs2.mutable._
-import scodec.bits._
-
-class SmallDeployableDataTest extends Specification {
- val string_boomer = hex"17 A5000000 CA0000F1630938D5A8F1400003F0031100"
-
- "SmallDeployableData" should {
- "decode (boomer)" in {
- PacketCoding.DecodePacket(string_boomer).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 165
- cls mustEqual ObjectClass.boomer
- guid mustEqual PlanetSideGUID(3840)
- parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[SmallDeployableData] mustEqual true
- val boomer = data.get.asInstanceOf[SmallDeployableData]
- boomer.pos.coord.x mustEqual 4704.172f
- boomer.pos.coord.y mustEqual 5546.4375f
- boomer.pos.coord.z mustEqual 82.234375f
- boomer.pos.orient.x mustEqual 0f
- boomer.pos.orient.y mustEqual 0f
- boomer.pos.orient.z mustEqual 272.8125f
- boomer.unk1 mustEqual 0
- boomer.owner_guid mustEqual PlanetSideGUID(8290)
- case _ =>
- ko
- }
- }
-
- "encode (boomer)" in {
- val obj = SmallDeployableData(
- PlacementData(Vector3(4704.172f, 5546.4375f, 82.234375f), Vector3.z(272.8125f)),
- PlanetSideEmpire.TR, false, false, 0, false, false, PlanetSideGUID(8290)
- )
- val msg = ObjectCreateMessage(ObjectClass.boomer, PlanetSideGUID(3840), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
- pkt mustEqual string_boomer
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/SmallTurretDataTest.scala b/common/src/test/scala/game/objectcreate/SmallTurretDataTest.scala
index ea0124d3..fc901305 100644
--- a/common/src/test/scala/game/objectcreate/SmallTurretDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/SmallTurretDataTest.scala
@@ -3,7 +3,7 @@ package game.objectcreate
import net.psforever.packet.PacketCoding
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate.{SmallDeployableData, _}
+import net.psforever.packet.game.objectcreate._
import net.psforever.types.{PlanetSideEmpire, Vector3}
import org.specs2.mutable._
import scodec.bits._
@@ -20,17 +20,25 @@ class SmallTurretDataTest extends Specification {
cls mustEqual ObjectClass.spitfire_turret
guid mustEqual PlanetSideGUID(4208)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[SmallTurretData] mustEqual true
- val turret = data.get.asInstanceOf[SmallTurretData]
- turret.deploy.pos.coord mustEqual Vector3(4577.7812f, 5624.828f, 72.046875f)
- turret.deploy.pos.orient mustEqual Vector3(0, 2.8125f, 264.375f)
- turret.deploy.faction mustEqual PlanetSideEmpire.NC
- turret.deploy.destroyed mustEqual true
- turret.deploy.unk1 mustEqual 2
- turret.deploy.owner_guid mustEqual PlanetSideGUID(7742)
- turret.health mustEqual 0
- turret.internals.isDefined mustEqual false
+ data match {
+ case SmallTurretData(CommonFieldDataWithPlacement(pos, deploy), health, None) =>
+ pos.coord mustEqual Vector3(4577.7812f, 5624.828f, 72.046875f)
+ pos.orient mustEqual Vector3(0, 2.8125f, 264.375f)
+
+ deploy.faction mustEqual PlanetSideEmpire.NC
+ deploy.bops mustEqual false
+ deploy.alternate mustEqual true
+ deploy.v1 mustEqual true
+ deploy.v2.isEmpty mustEqual true
+ deploy.v3 mustEqual false
+ deploy.v4.contains(false) mustEqual true
+ deploy.v5.isEmpty mustEqual true
+ deploy.guid mustEqual PlanetSideGUID(7742)
+
+ health mustEqual 0
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -43,31 +51,64 @@ class SmallTurretDataTest extends Specification {
cls mustEqual ObjectClass.spitfire_turret
guid mustEqual PlanetSideGUID(4265)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[SmallTurretData] mustEqual true
- val turret = data.get.asInstanceOf[SmallTurretData]
- turret.deploy.pos.coord mustEqual Vector3(4527.633f, 6271.3594f, 70.265625f)
- turret.deploy.pos.orient mustEqual Vector3(0, 0, 154.6875f)
- turret.deploy.faction mustEqual PlanetSideEmpire.VS
- turret.deploy.unk1 mustEqual 2
- turret.deploy.owner_guid mustEqual PlanetSideGUID(8208)
- turret.health mustEqual 255
- turret.internals.isDefined mustEqual true
- val internals = turret.internals.get.contents
- internals.head.objectClass mustEqual ObjectClass.spitfire_weapon
- internals.head.guid mustEqual PlanetSideGUID(3064)
- internals.head.parentSlot mustEqual 0
- internals.head.obj.isInstanceOf[WeaponData] mustEqual true
- val wep = internals.head.obj.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 0x6
- wep.unk2 mustEqual 0x8
- wep.fire_mode mustEqual 0
- val ammo = wep.ammo.head
- ammo.objectClass mustEqual ObjectClass.spitfire_ammo
- ammo.guid mustEqual PlanetSideGUID(3694)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 8
+ data match {
+ case SmallTurretData(CommonFieldDataWithPlacement(pos, deploy), health, Some(InventoryData(inv))) =>
+ pos.coord mustEqual Vector3(4527.633f, 6271.3594f, 70.265625f)
+ pos.orient mustEqual Vector3.z(154.6875f)
+
+ deploy.faction mustEqual PlanetSideEmpire.VS
+ deploy.bops mustEqual false
+ deploy.alternate mustEqual false
+ deploy.v1 mustEqual true
+ deploy.v2.isEmpty mustEqual true
+ deploy.v3 mustEqual false
+ deploy.v4.contains(true) mustEqual true
+ deploy.v5.isEmpty mustEqual true
+ deploy.guid mustEqual PlanetSideGUID(8208)
+
+ health mustEqual 255
+
+ inv.head.objectClass mustEqual ObjectClass.spitfire_weapon
+ inv.head.guid mustEqual PlanetSideGUID(3064)
+ inv.head.parentSlot mustEqual 0
+ inv.head.obj.isInstanceOf[WeaponData] mustEqual true
+ inv.head.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.spitfire_ammo
+ ammo.guid mustEqual PlanetSideGUID(3694)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -75,11 +116,11 @@ class SmallTurretDataTest extends Specification {
"encode (spitfire, short)" in {
val obj = SmallTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3(4577.7812f, 5624.828f, 72.046875f), Vector3(0, 2.8125f, 264.375f)),
- PlanetSideEmpire.NC, false, true, 2, false, false, PlanetSideGUID(7742)
+ CommonFieldData(PlanetSideEmpire.NC, false, true, true, None, false, Some(false), None, PlanetSideGUID(7742))
),
- 255 //sets to 0
+ 0
)
val msg = ObjectCreateMessage(ObjectClass.spitfire_turret, PlanetSideGUID(4208), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
@@ -88,12 +129,23 @@ class SmallTurretDataTest extends Specification {
"encode (spitfire)" in {
val obj = SmallTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3(4527.633f, 6271.3594f, 70.265625f), Vector3(0, 0, 154.6875f)),
- PlanetSideEmpire.VS, false, false, 2, false, true, PlanetSideGUID(8208)
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(true), None, PlanetSideGUID(8208))
),
255,
- InventoryData(List(SmallTurretData.spitfire(PlanetSideGUID(3064), 0x6, 0x8, PlanetSideGUID(3694), 8)))
+ InventoryData(List(
+ InternalSlot(ObjectClass.spitfire_weapon, PlanetSideGUID(3064), 0,
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.spitfire_ammo, PlanetSideGUID(3694), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0))
+ ))
+ )
+ )
+ //SmallTurretData.spitfire(PlanetSideGUID(3064), 0x6, 0x8, PlanetSideGUID(3694), 8)
+ ))
)
val msg = ObjectCreateMessage(ObjectClass.spitfire_turret, PlanetSideGUID(4265), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreate/TRAPDataTest.scala b/common/src/test/scala/game/objectcreate/TRAPDataTest.scala
index b8b89b6a..6e899523 100644
--- a/common/src/test/scala/game/objectcreate/TRAPDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/TRAPDataTest.scala
@@ -19,14 +19,23 @@ class TRAPDataTest extends Specification {
cls mustEqual ObjectClass.tank_traps
guid mustEqual PlanetSideGUID(2659)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[TRAPData] mustEqual true
- val trap = data.get.asInstanceOf[TRAPData]
- trap.deploy.pos.coord mustEqual Vector3(3572.4453f, 3277.9766f, 114.0f)
- trap.deploy.pos.orient mustEqual Vector3(0, 0, 90)
- trap.deploy.faction mustEqual PlanetSideEmpire.VS
- trap.deploy.owner_guid mustEqual PlanetSideGUID(4748)
- trap.health mustEqual 255
+ data match {
+ case TRAPData(CommonFieldDataWithPlacement(pos, deploy), health) =>
+ pos.coord mustEqual Vector3(3572.4453f, 3277.9766f, 114.0f)
+ pos.orient mustEqual Vector3.z(90)
+ deploy.faction mustEqual PlanetSideEmpire.VS
+ deploy.bops mustEqual false
+ deploy.alternate mustEqual false
+ deploy.v1 mustEqual true
+ deploy.v2.isEmpty mustEqual true
+ deploy.v3 mustEqual false
+ deploy.v4.contains(true) mustEqual true
+ deploy.v5.isEmpty mustEqual true
+ deploy.guid mustEqual PlanetSideGUID(4748)
+ health mustEqual 255
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -34,9 +43,9 @@ class TRAPDataTest extends Specification {
"encode" in {
val obj = TRAPData(
- SmallDeployableData(
- PlacementData(3572.4453f, 3277.9766f, 114.0f, 0f, 0f, 90.0f),
- PlanetSideEmpire.VS, false, false, 2, false, true, PlanetSideGUID(4748)
+ CommonFieldDataWithPlacement(
+ PlacementData(Vector3(3572.4453f, 3277.9766f, 114.0f), Vector3.z(90)),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(true), None, PlanetSideGUID(4748))
),
255
)
diff --git a/common/src/test/scala/game/objectcreate/TelepadDataTest.scala b/common/src/test/scala/game/objectcreate/TelepadDataTest.scala
deleted file mode 100644
index 10507986..00000000
--- a/common/src/test/scala/game/objectcreate/TelepadDataTest.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreate
-
-import net.psforever.packet._
-import net.psforever.packet.game._
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class TelepadDataTest extends Specification {
- val string = hex"17 86000000 5700 f3a a201 80 0302020000000"
- //TODO validate the unknown fields before router_guid for testing
-
- "TelepadData" should {
- "decode" in {
- PacketCoding.DecodePacket(string).require match {
- case ObjectCreateMessage(len, cls, guid, parent, data) =>
- len mustEqual 134
- cls mustEqual ObjectClass.router_telepad
- guid mustEqual PlanetSideGUID(418)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(430)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[TelepadData] mustEqual true
- data.get.asInstanceOf[TelepadData].router_guid mustEqual Some(PlanetSideGUID(385))
- case _ =>
- ko
- }
- }
-
- "encode" in {
- val obj = TelepadData(0, PlanetSideGUID(385))
- val msg = ObjectCreateMessage(ObjectClass.router_telepad, PlanetSideGUID(418), ObjectCreateMessageParent(PlanetSideGUID(430), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
-
- pkt mustEqual string
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreate/TelepadDeployableDataTest.scala b/common/src/test/scala/game/objectcreate/TelepadDeployableDataTest.scala
index e0d74b44..7f342a49 100644
--- a/common/src/test/scala/game/objectcreate/TelepadDeployableDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/TelepadDeployableDataTest.scala
@@ -20,37 +20,57 @@ class TelepadDeployableDataTest extends Specification {
cls mustEqual ObjectClass.router_telepad_deployable
guid mustEqual PlanetSideGUID(353)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[TelepadDeployableData] mustEqual true
- val teledata = data.get.asInstanceOf[TelepadDeployableData]
- teledata.pos.coord mustEqual Vector3(6559.961f, 1960.1172f, 13.640625f)
- teledata.pos.orient mustEqual Vector3.z(109.6875f)
- teledata.pos.vel.isDefined mustEqual false
- teledata.faction mustEqual PlanetSideEmpire.TR
- teledata.bops mustEqual false
- teledata.destroyed mustEqual false
- teledata.unk1 mustEqual 2
- teledata.unk2 mustEqual true
- teledata.router_guid mustEqual PlanetSideGUID(385)
- teledata.owner_guid mustEqual PlanetSideGUID(430)
- teledata.unk3 mustEqual 87
- teledata.unk4 mustEqual 12
+ data match {
+ case DroppedItemData(pos, telepad) =>
+ pos.coord mustEqual Vector3(6559.961f, 1960.1172f, 13.640625f)
+ pos.orient mustEqual Vector3.z(109.6875f)
+ pos.vel.isDefined mustEqual false
+
+ telepad match {
+ case TelepadDeployableData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), u1, u2) =>
+ faction mustEqual PlanetSideEmpire.TR
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.contains(385) mustEqual true
+ fguid mustEqual PlanetSideGUID(430)
+
+ u1 mustEqual 87
+ u2 mustEqual 12
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
"encode" in {
- val obj = TelepadDeployableData(
+ val obj = DroppedItemData(
PlacementData(
Vector3(6559.961f, 1960.1172f, 13.640625f),
Vector3.z(109.6875f)
),
- PlanetSideEmpire.TR,
- false, false, 2, true,
- PlanetSideGUID(385),
- PlanetSideGUID(430),
- 87, 12
+ TelepadDeployableData(
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ Some(385),
+ PlanetSideGUID(430)
+ ),
+ 87, 12
+ )
)
val msg = ObjectCreateMessage(ObjectClass.router_telepad_deployable, PlanetSideGUID(353), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreate/TrackedProjectileDataTest.scala b/common/src/test/scala/game/objectcreate/TrackedProjectileDataTest.scala
index 480c33be..998a50a3 100644
--- a/common/src/test/scala/game/objectcreate/TrackedProjectileDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/TrackedProjectileDataTest.scala
@@ -3,7 +3,8 @@ package game.objectcreate
import net.psforever.packet.PacketCoding
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
-import net.psforever.packet.game.objectcreate.{ObjectClass, PlacementData, TrackedProjectileData}
+import net.psforever.packet.game.objectcreate._
+import net.psforever.types.{PlanetSideEmpire, Vector3}
import org.specs2.mutable._
import scodec.bits._
@@ -11,32 +12,45 @@ class TrackedProjectileDataTest extends Specification {
val string_striker_projectile = hex"17 C5000000 A4B 009D 4C129 0CB0A 9814 00 F5 E3 040000666686400"
"TrackedProjectileData" should {
- "decode (striker projectile)" in {
+ "decode" in {
PacketCoding.DecodePacket(string_striker_projectile).require match {
case ObjectCreateMessage(len, cls, guid, parent, data) =>
len mustEqual 197
cls mustEqual ObjectClass.striker_missile_targeting_projectile
guid mustEqual PlanetSideGUID(40192)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[TrackedProjectileData] mustEqual true
- val projectile = data.get.asInstanceOf[TrackedProjectileData]
- projectile.pos.coord.x mustEqual 4644.5938f
- projectile.pos.coord.y mustEqual 5472.0938f
- projectile.pos.coord.z mustEqual 82.375f
- projectile.pos.orient.x mustEqual 0f
- projectile.pos.orient.y mustEqual 30.9375f
- projectile.pos.orient.z mustEqual 171.5625f
- projectile.unk1 mustEqual 0
- projectile.unk2 mustEqual TrackedProjectileData.striker_missile_targetting_projectile_data
+ data match {
+ case TrackedProjectileData(CommonFieldDataWithPlacement(pos, deploy), unk2, unk3) =>
+ pos.coord mustEqual Vector3(4644.5938f, 5472.0938f, 82.375f)
+ pos.orient mustEqual Vector3(0, 30.9375f, 171.5625f)
+ deploy.faction mustEqual PlanetSideEmpire.TR
+ deploy.bops mustEqual false
+ deploy.alternate mustEqual false
+ deploy.v1 mustEqual true
+ deploy.v2.isEmpty mustEqual true
+ deploy.v3 mustEqual false
+ deploy.v4.isEmpty mustEqual true
+ deploy.v5.isEmpty mustEqual true
+ deploy.guid mustEqual PlanetSideGUID(0)
+
+ unk2 mustEqual TrackedProjectile.Striker
+
+ unk3 mustEqual 0
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
- "encode (striker projectile)" in {
- val obj = TrackedProjectileData.striker(
- PlacementData(4644.5938f, 5472.0938f, 82.375f, 0f, 30.9375f, 171.5625f),
+ "encode" in {
+ val obj = TrackedProjectileData(
+ CommonFieldDataWithPlacement(
+ PlacementData(4644.5938f, 5472.0938f, 82.375f, 0f, 30.9375f, 171.5625f),
+ CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ ),
+ TrackedProjectile.Striker,
0
)
val msg = ObjectCreateMessage(ObjectClass.striker_missile_targeting_projectile, PlanetSideGUID(40192), obj)
@@ -46,25 +60,5 @@ class TrackedProjectileDataTest extends Specification {
pkt.toBitVector.drop(133).take(7) mustEqual string_striker_projectile.toBitVector.drop(133).take(7)
pkt.toBitVector.drop(141) mustEqual string_striker_projectile.toBitVector.drop(141)
}
-
- "hunter_seeker" in {
- TrackedProjectileData.hunter_seeker(PlacementData(0f, 0f, 0f), 0) mustEqual
- TrackedProjectileData(PlacementData(0f, 0f, 0f), 0, TrackedProjectileData.hunter_seeker_missile_projectile_data)
- }
-
- "oicw" in {
- TrackedProjectileData.oicw(PlacementData(0f, 0f, 0f), 0) mustEqual
- TrackedProjectileData(PlacementData(0f, 0f, 0f), 0, TrackedProjectileData.oicw_projectile_data)
- }
-
- "starfire" in {
- TrackedProjectileData.starfire(PlacementData(0f, 0f, 0f), 0) mustEqual
- TrackedProjectileData(PlacementData(0f, 0f, 0f), 0, TrackedProjectileData.starfire_projectile_data)
- }
-
- "striker" in {
- TrackedProjectileData.striker(PlacementData(0f, 0f, 0f), 0) mustEqual
- TrackedProjectileData(PlacementData(0f, 0f, 0f), 0, TrackedProjectileData.striker_missile_targetting_projectile_data)
- }
}
}
diff --git a/common/src/test/scala/game/objectcreate/WeaponDataTest.scala b/common/src/test/scala/game/objectcreate/WeaponDataTest.scala
index b4b87b0c..c9e504bd 100644
--- a/common/src/test/scala/game/objectcreate/WeaponDataTest.scala
+++ b/common/src/test/scala/game/objectcreate/WeaponDataTest.scala
@@ -4,6 +4,7 @@ package game.objectcreate
import net.psforever.packet.PacketCoding
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import org.specs2.mutable._
import scodec.bits._
@@ -23,18 +24,40 @@ class WeaponDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(4141)
parent.get.slot mustEqual 3
- data.isDefined mustEqual true
- data.get.isInstanceOf[WeaponData] mustEqual true
- val wep = data.get.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 4
- wep.unk2 mustEqual 8
- wep.fire_mode mustEqual 0
- wep.ammo.head.objectClass mustEqual ObjectClass.energy_cell
- wep.ammo.head.guid mustEqual PlanetSideGUID(3548)
- wep.ammo.head.parentSlot mustEqual 0
- wep.ammo.head.obj.isInstanceOf[AmmoBoxData] mustEqual true
- val ammo = wep.ammo.head.obj.asInstanceOf[AmmoBoxData]
- ammo.unk mustEqual 8
+ data match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.VS
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.energy_cell
+ ammo.guid mustEqual PlanetSideGUID(3548)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -49,26 +72,59 @@ class WeaponDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(3092)
parent.get.slot mustEqual 3
- data.isDefined mustEqual true
- data.get.isInstanceOf[WeaponData] mustEqual true
- val wep = data.get.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 4
- wep.unk2 mustEqual 8
- wep.fire_mode mustEqual 0
- val ammo = wep.ammo
- ammo.size mustEqual 2
- //0
- ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
- ammo.head.guid mustEqual PlanetSideGUID(3918)
- ammo.head.parentSlot mustEqual 0
- ammo.head.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.head.obj.asInstanceOf[AmmoBoxData].unk mustEqual 8
- //1
- ammo(1).objectClass mustEqual ObjectClass.rocket
- ammo(1).guid mustEqual PlanetSideGUID(3941)
- ammo(1).parentSlot mustEqual 1
- ammo(1).obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo(1).obj.asInstanceOf[AmmoBoxData].unk mustEqual 8
+ data match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, ammo, _) =>
+ wfaction mustEqual PlanetSideEmpire.VS
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+ //0
+ ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
+ ammo.head.guid mustEqual PlanetSideGUID(3918)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ //1
+ //1
+ ammo(1).objectClass mustEqual ObjectClass.rocket
+ ammo(1).guid mustEqual PlanetSideGUID(3941)
+ ammo(1).parentSlot mustEqual 1
+ ammo(1).obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -81,26 +137,48 @@ class WeaponDataTest extends Specification {
cls mustEqual ObjectClass.lasher
guid mustEqual PlanetSideGUID(3074)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
+ data.isInstanceOf[DroppedItemData[_]] mustEqual true
+ val drop = data.asInstanceOf[DroppedItemData[_]]
drop.pos.coord.x mustEqual 4691.1953f
drop.pos.coord.y mustEqual 5537.039f
drop.pos.coord.z mustEqual 65.484375f
drop.pos.orient.x mustEqual 0f
drop.pos.orient.y mustEqual 0f
drop.pos.orient.z mustEqual 0f
- drop.obj.isInstanceOf[WeaponData] mustEqual true
- val wep = drop.obj.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 4
- wep.unk2 mustEqual 0
- wep.fire_mode mustEqual 0
- wep.ammo.head.objectClass mustEqual ObjectClass.energy_cell
- wep.ammo.head.guid mustEqual PlanetSideGUID(3268)
- wep.ammo.head.parentSlot mustEqual 0
- wep.ammo.head.obj.isInstanceOf[AmmoBoxData] mustEqual true
- val ammo = wep.ammo.head.obj.asInstanceOf[AmmoBoxData]
- ammo.unk mustEqual 0
+ drop.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.VS
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual false
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.energy_cell
+ ammo.guid mustEqual PlanetSideGUID(3268)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -113,41 +191,78 @@ class WeaponDataTest extends Specification {
cls mustEqual ObjectClass.punisher
guid mustEqual PlanetSideGUID(2978)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppedItemData[_]] mustEqual true
- val drop = data.get.asInstanceOf[DroppedItemData[_]]
+ data.isInstanceOf[DroppedItemData[_]] mustEqual true
+ val drop = data.asInstanceOf[DroppedItemData[_]]
drop.pos.coord.x mustEqual 4789.133f
drop.pos.coord.y mustEqual 5522.3125f
drop.pos.coord.z mustEqual 72.3125f
drop.pos.orient.x mustEqual 0f
drop.pos.orient.y mustEqual 0f
drop.pos.orient.z mustEqual 306.5625f
- drop.obj.isInstanceOf[WeaponData] mustEqual true
- val wep = drop.obj.asInstanceOf[WeaponData]
- wep.unk1 mustEqual 2
- wep.unk2 mustEqual 0
- wep.fire_mode mustEqual 0
- val ammo = wep.ammo
- ammo.size mustEqual 2
- //0
- ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
- ammo.head.guid mustEqual PlanetSideGUID(3528)
- ammo.head.parentSlot mustEqual 0
- ammo.head.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.head.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0
- //1
- ammo(1).objectClass mustEqual ObjectClass.rocket
- ammo(1).guid mustEqual PlanetSideGUID(3031)
- ammo(1).parentSlot mustEqual 1
- ammo(1).obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo(1).obj.asInstanceOf[AmmoBoxData].unk mustEqual 0
+ drop.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, ammo, _) =>
+ wfaction mustEqual PlanetSideEmpire.NC
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual false
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+ //0
+ ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
+ ammo.head.guid mustEqual PlanetSideGUID(3528)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ //1
+ //1
+ ammo(1).objectClass mustEqual ObjectClass.rocket
+ ammo(1).guid mustEqual PlanetSideGUID(3031)
+ ammo(1).parentSlot mustEqual 1
+ ammo(1).obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
"encode (lasher, held)" in {
- val obj = WeaponData(4, 8, ObjectClass.energy_cell, PlanetSideGUID(3548), 0, AmmoBoxData(8))
+ val obj = WeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(3548), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)))
+ )
val msg = ObjectCreateMessage(ObjectClass.lasher, PlanetSideGUID(3033), ObjectCreateMessageParent(PlanetSideGUID(4141), 3), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_lasher_held
@@ -155,11 +270,14 @@ class WeaponDataTest extends Specification {
"encode (punisher, held)" in {
val obj =
- WeaponData(4, 8, 0,
- AmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(3918), 0, AmmoBoxData(8)) ::
- AmmoBoxData(ObjectClass.rocket, PlanetSideGUID(3941), 1, AmmoBoxData(8)) ::
- Nil
- )(2)
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ AmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(3918), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)),
+ AmmoBoxData(ObjectClass.rocket, PlanetSideGUID(3941), 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
+ )
+ )
val msg = ObjectCreateMessage(ObjectClass.punisher, PlanetSideGUID(4147), ObjectCreateMessageParent(PlanetSideGUID(3092), 3), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_punisher_held
@@ -168,7 +286,11 @@ class WeaponDataTest extends Specification {
"encode (lasher, dropped)" in {
val obj = DroppedItemData(
PlacementData(4691.1953f, 5537.039f, 65.484375f, 0.0f, 0.0f, 0.0f),
- WeaponData(4, 0, ObjectClass.energy_cell, PlanetSideGUID(3268), 0, AmmoBoxData())
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(3268), 0, CommonFieldData()(false)))
+ )
)
val msg = ObjectCreateMessage(ObjectClass.lasher, PlanetSideGUID(3074), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
@@ -178,11 +300,14 @@ class WeaponDataTest extends Specification {
"encode (punisher, dropped)" in {
val obj = DroppedItemData(
PlacementData(4789.133f, 5522.3125f, 72.3125f, 0f, 0f, 306.5625f),
- WeaponData(2, 0, 0,
- AmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(3528), 0, AmmoBoxData()) ::
- AmmoBoxData(ObjectClass.rocket, PlanetSideGUID(3031), 1, AmmoBoxData()) ::
- Nil
- )(2)
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NC, false, false, false, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ AmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(3528), 0, CommonFieldData()(false)),
+ AmmoBoxData(ObjectClass.rocket, PlanetSideGUID(3031), 1, CommonFieldData()(false))
+ )
+ )
)
val msg = ObjectCreateMessage(ObjectClass.punisher, PlanetSideGUID(2978), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedACEDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedACEDataTest.scala
deleted file mode 100644
index 24214f09..00000000
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedACEDataTest.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreatedetailed
-
-import org.specs2.mutable._
-import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
-import net.psforever.packet.game.objectcreate._
-import scodec.bits._
-
-class DetailedACEDataTest extends Specification {
- val string_ace = hex"18 87000000 1006 100 C70B 80 8800000200008"
-
- "DetailedACEData" should {
- "decode" in {
- PacketCoding.DecodePacket(string_ace).require match {
- case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
- len mustEqual 135
- cls mustEqual ObjectClass.ace
- guid mustEqual PlanetSideGUID(3015)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(3104)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[DetailedACEData] mustEqual true
- data.get.asInstanceOf[DetailedACEData].unk mustEqual 8
- case _ =>
- ko
- }
- }
-
- "encode" in {
- val obj = DetailedACEData(8)
- val msg = ObjectCreateDetailedMessage(ObjectClass.ace, PlanetSideGUID(3015), ObjectCreateMessageParent(PlanetSideGUID(3104), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
-
- pkt mustEqual string_ace
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedAmmoBoxDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedAmmoBoxDataTest.scala
index 0b9ae180..b3afa5cf 100644
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedAmmoBoxDataTest.scala
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedAmmoBoxDataTest.scala
@@ -20,8 +20,7 @@ class DetailedAmmoBoxDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(75)
parent.get.slot mustEqual 33
- data.isDefined mustEqual true
- data.get.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
+ data.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 50
case _ =>
ko
}
@@ -30,7 +29,8 @@ class DetailedAmmoBoxDataTest extends Specification {
"encode (9mm)" in {
val obj = DetailedAmmoBoxData(8, 50)
val msg = ObjectCreateDetailedMessage(ObjectClass.bullet_9mm, PlanetSideGUID(1280), ObjectCreateMessageParent(PlanetSideGUID(75), 33), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+ val out = PacketCoding.EncodePacket(msg)
+ val pkt = out.require.toByteVector
pkt mustEqual string_9mm
}
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedBoomerTriggerDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedBoomerTriggerDataTest.scala
deleted file mode 100644
index e67d5de6..00000000
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedBoomerTriggerDataTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreatedetailed
-
-import org.specs2.mutable._
-import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
-import net.psforever.packet.game.objectcreate._
-import scodec.bits._
-
-class DetailedBoomerTriggerDataTest extends Specification {
- val string_boomer_trigger = hex"18 87000000 6304CA8760B 80 C800000200008"
-
- "DetailedBoomerTriggerData" should {
- "decode" in {
- PacketCoding.DecodePacket(string_boomer_trigger).require match {
- case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
- len mustEqual 135
- cls mustEqual ObjectClass.boomer_trigger
- guid mustEqual PlanetSideGUID(2934)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(2502)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[DetailedBoomerTriggerData] mustEqual true
- case _ =>
- ko
- }
- }
-
- "encode" in {
- val obj = DetailedBoomerTriggerData()
- val msg = ObjectCreateDetailedMessage(ObjectClass.boomer_trigger, PlanetSideGUID(2934), ObjectCreateMessageParent(PlanetSideGUID(2502), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
-
- pkt mustEqual string_boomer_trigger
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala
index b611f048..84bdd517 100644
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala
@@ -55,7 +55,7 @@ class DetailedCharacterDataTest extends Specification {
guid mustEqual PlanetSideGUID(75)
parent.isDefined mustEqual false
data match {
- case Some(DetailedPlayerData(Some(pos), basic, char, inv, hand)) =>
+ case DetailedPlayerData(Some(pos), basic, char, inv, hand) =>
pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
pos.orient mustEqual Vector3(0, 0, 36.5625f)
pos.vel.isDefined mustEqual false
@@ -67,13 +67,13 @@ class DetailedCharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Female
a.app.head mustEqual 41
a.app.voice mustEqual CharacterVoice.Voice1
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual true
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Standard
- a.unk1 mustEqual true
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 41605313L
a.unk7 mustEqual 0
@@ -90,7 +90,7 @@ class DetailedCharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 0L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -117,7 +117,7 @@ class DetailedCharacterDataTest extends Specification {
a.armor mustEqual 50 //standard exosuit value
a.staminaMax mustEqual 100
a.stamina mustEqual 100
- a.max_field mustEqual None
+ a.max_field.isEmpty mustEqual true
a.certs mustEqual List(
CertificationType.StandardAssault,
CertificationType.MediumAssault,
@@ -145,8 +145,8 @@ class DetailedCharacterDataTest extends Specification {
"map13"
)
b.tutorials mustEqual Nil
- b.cosmetics mustEqual None
- b.unk1 mustEqual None
+ b.cosmetics.isEmpty mustEqual true
+ b.unk1.isEmpty mustEqual true
b.unk2 mustEqual Nil
b.unk3 mustEqual Nil
b.unk4 mustEqual 0L
@@ -154,7 +154,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual 0L
b.unk7 mustEqual 0L
b.unk8 mustEqual 0L
- b.unk9 mustEqual Some(DCDExtra2(0, 0))
+ b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
b.unkA mustEqual Nil
b.unkB mustEqual Nil
b.unkC mustEqual false
@@ -247,7 +247,7 @@ class DetailedCharacterDataTest extends Specification {
parent.get.guid mustEqual PlanetSideGUID(43981)
parent.get.slot mustEqual 0
data match {
- case Some(DetailedPlayerData(None, basic, char, inv, hand)) =>
+ case DetailedPlayerData(None, basic, char, inv, hand) =>
basic match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app.name mustEqual "IlllIIIlllIlIllIlllIllI"
@@ -255,13 +255,13 @@ class DetailedCharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Female
a.app.head mustEqual 41
a.app.voice mustEqual CharacterVoice.Voice1
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Standard
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 192L
a.unk7 mustEqual 0
@@ -278,7 +278,7 @@ class DetailedCharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 0L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -305,7 +305,7 @@ class DetailedCharacterDataTest extends Specification {
a.armor mustEqual 50 //standard exosuit value
a.staminaMax mustEqual 100
a.stamina mustEqual 100
- a.max_field mustEqual None
+ a.max_field.isEmpty mustEqual true
a.certs mustEqual List(
CertificationType.StandardAssault,
CertificationType.MediumAssault,
@@ -333,8 +333,8 @@ class DetailedCharacterDataTest extends Specification {
"map13"
)
b.tutorials mustEqual Nil
- b.cosmetics mustEqual None
- b.unk1 mustEqual None
+ b.cosmetics.isEmpty mustEqual true
+ b.unk1.isEmpty mustEqual true
b.unk2 mustEqual Nil
b.unk3 mustEqual Nil
b.unk4 mustEqual 0L
@@ -342,7 +342,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual 0L
b.unk7 mustEqual 0L
b.unk8 mustEqual 0L
- b.unk9 mustEqual Some(DCDExtra2(0, 0))
+ b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
b.unkA mustEqual Nil
b.unkB mustEqual Nil
b.unkC mustEqual false
@@ -432,7 +432,7 @@ class DetailedCharacterDataTest extends Specification {
//the object produced is massive and most of it is already covered in other tests
//only certain details towards the end of the stream will be checked
data match {
- case Some(DetailedPlayerData(Some(p), basic, char, inv, hand)) =>
+ case DetailedPlayerData(Some(_), basic, char, inv, hand) =>
basic match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app.name mustEqual "HaHaATRMax"
@@ -440,13 +440,13 @@ class DetailedCharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Male
a.app.head mustEqual 57
a.app.voice mustEqual CharacterVoice.Voice1
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual true
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.MAX
- a.unk1 mustEqual true
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 1
a.unk6 mustEqual 41605870L
a.unk7 mustEqual 0
@@ -463,7 +463,7 @@ class DetailedCharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 0L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -491,7 +491,7 @@ class DetailedCharacterDataTest extends Specification {
a.armor mustEqual 641
a.staminaMax mustEqual 100
a.stamina mustEqual 100
- a.max_field mustEqual Some(0) //important!
+ a.max_field.contains(0) mustEqual true //important!
a.certs mustEqual List(
CertificationType.StandardAssault,
CertificationType.MediumAssault,
@@ -561,8 +561,8 @@ class DetailedCharacterDataTest extends Specification {
"map02"
)
b.tutorials mustEqual Nil
- b.cosmetics mustEqual None
- b.unk1 mustEqual None
+ b.cosmetics.isEmpty mustEqual true
+ b.unk1.isEmpty mustEqual true
b.unk2 mustEqual Nil
b.unk3 mustEqual Nil
b.unk4 mustEqual 0L
@@ -570,7 +570,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual 0L
b.unk7 mustEqual 0L
b.unk8 mustEqual 0L
- b.unk9 mustEqual Some(DCDExtra2(0, 0))
+ b.unk9.contains(DCDExtra2(0, 0)) mustEqual true
b.unkA mustEqual Nil
b.unkB mustEqual Nil
b.unkC mustEqual false
@@ -583,18 +583,29 @@ class DetailedCharacterDataTest extends Specification {
val contents = inv.get.contents
//0
contents.head mustEqual InternalSlot(889, PlanetSideGUID(2), 0,
- DetailedWeaponData(0,8,0, List(
- InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8,200)),
- InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8,200)),
- InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8,200))
- ))
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8,200)),
+ InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8,200)),
+ InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8,200))
+ )
+ )
)
contents(1) mustEqual InternalSlot(175, PlanetSideGUID(6), 4,
- DetailedWeaponData(0,8,0, List(
- InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8,1))
- ))
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8,1))
+ )
+ )
)
- contents(2) mustEqual InternalSlot(456, PlanetSideGUID(8), 5, DetailedLockerContainerData(8, None))
+ contents(2) mustEqual InternalSlot(456, PlanetSideGUID(8), 5, DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ None
+ ))
contents(3) mustEqual InternalSlot(265, PlanetSideGUID(9), 6, DetailedAmmoBoxData(8, 36))
contents(4) mustEqual InternalSlot(265, PlanetSideGUID(10), 10, DetailedAmmoBoxData(8, 100))
contents(5) mustEqual InternalSlot(265, PlanetSideGUID(11), 14, DetailedAmmoBoxData(8, 100))
@@ -629,7 +640,7 @@ class DetailedCharacterDataTest extends Specification {
//the object produced is massive and most of it is already covered in other tests
//only certain details towards the end of the stream will be checked
data match {
- case Some(DetailedPlayerData(Some(_), basic, char, inv, hand)) =>
+ case DetailedPlayerData(Some(_), basic, char, inv, hand) =>
basic match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app.name mustEqual "KiCkJr"
@@ -637,13 +648,13 @@ class DetailedCharacterDataTest extends Specification {
a.app.sex mustEqual CharacterGender.Male
a.app.head mustEqual 24
a.app.voice mustEqual CharacterVoice.Voice4
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual true
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Agile
- a.unk1 mustEqual true
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 733931L
a.unk7 mustEqual 0
@@ -660,7 +671,7 @@ class DetailedCharacterDataTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 556539L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -688,7 +699,7 @@ class DetailedCharacterDataTest extends Specification {
a.armor mustEqual 100 //standard exosuit value
a.staminaMax mustEqual 100
a.stamina mustEqual 46
- a.max_field mustEqual None
+ a.max_field.isEmpty mustEqual true
a.certs mustEqual List(
CertificationType.StandardAssault,
CertificationType.MediumAssault,
@@ -1026,10 +1037,13 @@ class DetailedCharacterDataTest extends Specification {
"training_ui",
"training_map"
)
- b.cosmetics mustEqual Some(
- Cosmetics(true, true, true, true, false)
- )
- b.unk1 mustEqual None
+ b.cosmetics match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Beret, PersonalStyle.Sunglasses, PersonalStyle.Earpiece)
+ case None =>
+ ko
+ }
+ b.unk1.isEmpty mustEqual true
b.unk2 mustEqual Nil
b.unk3 mustEqual Nil
b.unk4 mustEqual 0L
@@ -1037,7 +1051,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual 0L
b.unk7 mustEqual 0L
b.unk8 mustEqual 0L
- b.unk9 mustEqual None
+ b.unk9.isEmpty mustEqual true
b.unkA mustEqual Nil
b.unkB mustEqual Nil
b.unkC mustEqual false
@@ -1051,31 +1065,77 @@ class DetailedCharacterDataTest extends Specification {
inv.get.contents.head.objectClass mustEqual 531
inv.get.contents.head.guid mustEqual PlanetSideGUID(4202)
inv.get.contents.head.parentSlot mustEqual 0
- val wep1 = inv.get.contents.head.obj.asInstanceOf[DetailedWeaponData]
- wep1.unk1 mustEqual 2
- wep1.unk2 mustEqual 8
- wep1.ammo.head.objectClass mustEqual 389
- wep1.ammo.head.guid mustEqual PlanetSideGUID(3942)
- wep1.ammo.head.parentSlot mustEqual 0
- wep1.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].unk mustEqual 8
- wep1.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 100
+ inv.get.contents.head.obj match {
+ case DetailedWeaponData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), fmode, ammo, _) =>
+ faction mustEqual PlanetSideEmpire.NC
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.head.objectClass mustEqual 389
+ ammo.head.guid mustEqual PlanetSideGUID(3942)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].data.v1 mustEqual true
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 100
+ case _ =>
+ ko
+ }
//4
inv.get.contents(4).objectClass mustEqual 456
inv.get.contents(4).guid mustEqual PlanetSideGUID(5374)
inv.get.contents(4).parentSlot mustEqual 5
inv.get.contents(4).obj.asInstanceOf[DetailedLockerContainerData].inventory.get.contents.size mustEqual 61
+ //10
+ inv.get.contents(10).objectClass mustEqual 32
+ inv.get.contents(10).guid mustEqual PlanetSideGUID(5523)
+ inv.get.contents(10).parentSlot mustEqual 39
+ inv.get.contents(10).obj match {
+ case cdata : DetailedConstructionToolData =>
+ cdata.data.faction mustEqual PlanetSideEmpire.NC
+ cdata.data.bops mustEqual false
+ cdata.data.alternate mustEqual false
+ cdata.data.v1 mustEqual true
+ cdata.data.v2.isEmpty mustEqual true
+ cdata.data.v3 mustEqual false
+ cdata.data.v4.isEmpty mustEqual true
+ cdata.data.v5.isEmpty mustEqual true
+ cdata.data.guid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
//11
inv.get.contents(11).objectClass mustEqual 673
inv.get.contents(11).guid mustEqual PlanetSideGUID(3661)
inv.get.contents(11).parentSlot mustEqual 60
- val wep2 = inv.get.contents(11).obj.asInstanceOf[DetailedWeaponData]
- wep2.unk1 mustEqual 2
- wep2.unk2 mustEqual 8
- wep2.ammo.head.objectClass mustEqual 674
- wep2.ammo.head.guid mustEqual PlanetSideGUID(8542)
- wep2.ammo.head.parentSlot mustEqual 0
- wep2.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].unk mustEqual 8
- wep2.ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 3
+ inv.get.contents(11).obj match {
+ case DetailedWeaponData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), fmode, ammo, _) =>
+ faction mustEqual PlanetSideEmpire.NC
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.head.objectClass mustEqual 674
+ ammo.head.guid mustEqual PlanetSideGUID(8542)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].data.v1 mustEqual true
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 3
+ case _ =>
+ ko
+ }
hand mustEqual DrawnSlot.None
case _ =>
@@ -1091,18 +1151,18 @@ class DetailedCharacterDataTest extends Specification {
case ObjectCreateDetailedMessage(len, _, _, None, data) =>
len mustEqual 51018L
data match {
- case Some(DetailedPlayerData(_, basic, char, _, _)) =>
+ case DetailedPlayerData(_, basic, char, inv, _) =>
basic match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app mustEqual BasicCharacterData("CCRIDER", PlanetSideEmpire.NC, CharacterGender.Male, 20, CharacterVoice.Voice3)
- a.black_ops mustEqual false
- a.altModel mustEqual false
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.alternate mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Standard
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 1176612L
a.unk7 mustEqual 15
@@ -1127,7 +1187,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual false
b.charging_pose mustEqual false
b.unk7 mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
ribbons.upper mustEqual MeritCommendation.DefenseNC5
ribbons.middle mustEqual MeritCommendation.HackingSupport5
@@ -1151,7 +1211,7 @@ class DetailedCharacterDataTest extends Specification {
a.unk5 mustEqual 32831L
a.staminaMax mustEqual 100
a.stamina mustEqual 100
- a.max_field mustEqual None
+ a.max_field.isEmpty mustEqual true
a.unk6 mustEqual 0
a.unk7 mustEqual 6
a.unk8 mustEqual 3165669L
@@ -1172,7 +1232,7 @@ class DetailedCharacterDataTest extends Specification {
CertificationType.Engineering
)
- b.unk1 mustEqual Some(14140)
+ b.unk1.contains(14140) mustEqual true
b.implants mustEqual List(
ImplantEntry(ImplantType.Surge, Some(94), false),
ImplantEntry(ImplantType.DarklightVision, Some(91), false),
@@ -1196,7 +1256,7 @@ class DetailedCharacterDataTest extends Specification {
b.unk6 mustEqual 0L
b.unk7 mustEqual 0L
b.unk8 mustEqual 0L
- b.unk9 mustEqual None
+ b.unk9.isEmpty mustEqual true
b.unkA.size mustEqual 86
b.unkA mustEqual List(
9,
@@ -1212,7 +1272,13 @@ class DetailedCharacterDataTest extends Specification {
)
b.unkB mustEqual List()
b.unkC mustEqual false
- b.cosmetics mustEqual Some(Cosmetics(true, false, true, true, true))
+ b.cosmetics match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.NoHelmet, PersonalStyle.Sunglasses, PersonalStyle.Earpiece, PersonalStyle.BrimmedCap)
+ case None =>
+ ko
+ }
+ b.cosmetics.contains(Cosmetics(true, false, true, true, true)) mustEqual true
case _ =>
ko
}
@@ -1237,14 +1303,18 @@ class DetailedCharacterDataTest extends Specification {
41,
CharacterVoice.Voice1
),
- false,
- false,
- true,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.VS,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Standard,
- None,
- 0,
0,
41605313L,
0,
@@ -1272,7 +1342,7 @@ class DetailedCharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
aa, ab,
RibbonBars(
MeritCommendation.None,
@@ -1319,25 +1389,38 @@ class DetailedCharacterDataTest extends Specification {
Nil, Nil, false,
None
)
- val char : (Option[Int])=>DetailedCharacterData =
+ val char : Option[Int]=>DetailedCharacterData =
(pad_length : Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)
- val inv = InventoryData(
+ val inv = InventoryData(List(
InventoryItemData(ObjectClass.beamer, PlanetSideGUID(76), 0,
- DetailedWeaponData(4, 8, ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16))) ::
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16)))
+ )
+ ),
InventoryItemData(ObjectClass.suppressor, PlanetSideGUID(78), 2,
- DetailedWeaponData(4, 8, ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25))) ::
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25)))
+ )
+ ),
InventoryItemData(ObjectClass.forceblade, PlanetSideGUID(80), 4,
- DetailedWeaponData(4, 8, ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1))) ::
- InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.remote_electronics_kit, PlanetSideGUID(88), 39, DetailedREKData(8)) ::
- Nil
- )
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1)))
+ )
+ ),
+ InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.remote_electronics_kit, PlanetSideGUID(88), 39, DetailedREKData(CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0))))
+ ))
val obj = DetailedPlayerData.apply(pos, app, char, inv, DrawnSlot.Pistol1)
val msg = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
@@ -1358,14 +1441,18 @@ class DetailedCharacterDataTest extends Specification {
41,
CharacterVoice.Voice1
),
- false,
- false,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.VS,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Standard,
- None,
- 0,
0,
192L,
0,
@@ -1393,7 +1480,7 @@ class DetailedCharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
aa, ab,
RibbonBars(
MeritCommendation.None,
@@ -1440,22 +1527,38 @@ class DetailedCharacterDataTest extends Specification {
Nil, Nil, false,
None
)
- val char : (Option[Int])=>DetailedCharacterData =
+ val char : Option[Int]=>DetailedCharacterData =
(pad_length : Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)
- val inv = InventoryData(
- InventoryItemData(ObjectClass.beamer, PlanetSideGUID(76), 0, DetailedWeaponData(4, 8, ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16))) ::
- InventoryItemData(ObjectClass.suppressor, PlanetSideGUID(78), 2, DetailedWeaponData(4, 8, ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25))) ::
- InventoryItemData(ObjectClass.forceblade, PlanetSideGUID(80), 4, DetailedWeaponData(4, 8, ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1))) ::
- InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)) ::
- InventoryItemData(ObjectClass.remote_electronics_kit, PlanetSideGUID(88), 39, DetailedREKData(8)) ::
- Nil
- )
+ val inv = InventoryData(List(
+ InventoryItemData(ObjectClass.beamer, PlanetSideGUID(76), 0,
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.energy_cell, PlanetSideGUID(77), 0, DetailedAmmoBoxData(8, 16)))
+ )
+ ),
+ InventoryItemData(ObjectClass.suppressor, PlanetSideGUID(78), 2,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(79), 0, DetailedAmmoBoxData(8, 25)))
+ )
+ ),
+ InventoryItemData(ObjectClass.forceblade, PlanetSideGUID(80), 4,
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(81), 0, DetailedAmmoBoxData(8, 1)))
+ )
+ ),
+ InventoryItemData(ObjectClass.locker_container, PlanetSideGUID(82), 5, DetailedLockerContainerData(8)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(83), 6, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(84), 9, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm, PlanetSideGUID(85), 12, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.bullet_9mm_AP, PlanetSideGUID(86), 33, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.energy_cell, PlanetSideGUID(87), 36, DetailedAmmoBoxData(8, 50)),
+ InventoryItemData(ObjectClass.remote_electronics_kit, PlanetSideGUID(88), 39, DetailedREKData(CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0))))
+ ))
val obj = DetailedPlayerData.apply(app, char, inv, DrawnSlot.Pistol1)
//it shouldn't be Pistol1 if he's seated but it's fine for the test
@@ -1481,15 +1584,18 @@ class DetailedCharacterDataTest extends Specification {
CharacterGender.Male,
57,
CharacterVoice.Voice1
+ ),CommonFieldData(
+ PlanetSideEmpire.TR,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
),
- false,
- false,
- true,
- None,
- false,
ExoSuitType.MAX,
- None,
- 0,
1,
41605870L,
0,
@@ -1517,7 +1623,7 @@ class DetailedCharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
aa, ab,
RibbonBars()
)
@@ -1601,24 +1707,34 @@ class DetailedCharacterDataTest extends Specification {
Nil, Nil, false,
None
)
- val char : (Option[Int])=>DetailedCharacterData =
+ val char : Option[Int]=>DetailedCharacterData =
(pad_length : Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)
val inv = InventoryData(
List(
InternalSlot(889, PlanetSideGUID(2), 0,
- DetailedWeaponData(0,8,0, List(
- InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8,200)),
- InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8,200)),
- InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8,200))
- ))
+ DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ InternalSlot(265, PlanetSideGUID(3), 0, DetailedAmmoBoxData(8,200)),
+ InternalSlot(265, PlanetSideGUID(4), 1, DetailedAmmoBoxData(8,200)),
+ InternalSlot(265, PlanetSideGUID(5), 2, DetailedAmmoBoxData(8,200))
+ )
+ )
),
InternalSlot(175, PlanetSideGUID(6), 4,
- DetailedWeaponData(0,8,0, List(
- InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8,1))
- ))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ InternalSlot(540, PlanetSideGUID(7), 0, DetailedAmmoBoxData(8,1))
+ )
+ )
),
- InternalSlot(456, PlanetSideGUID(8), 5, DetailedLockerContainerData(8, None)),
+ InternalSlot(456, PlanetSideGUID(8), 5, DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ None
+ )),
InternalSlot(265, PlanetSideGUID(9), 6, DetailedAmmoBoxData(8, 36)),
InternalSlot(265, PlanetSideGUID(10), 10, DetailedAmmoBoxData(8, 100)),
InternalSlot(265, PlanetSideGUID(11), 14, DetailedAmmoBoxData(8, 100)),
@@ -1644,7 +1760,7 @@ class DetailedCharacterDataTest extends Specification {
pkt mustEqual string_max
}
- "encode (character, br32)" in {
+ "encode (BR32)" in {
val pos : PlacementData = PlacementData(
Vector3(5500.0f, 3800.0f, 71.484375f),
Vector3(0, 0, 90.0f),
@@ -1658,14 +1774,18 @@ class DetailedCharacterDataTest extends Specification {
24,
CharacterVoice.Voice4
),
- false,
- false,
- true,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.NC,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Agile,
- None,
- 0,
0,
733931L,
0,
@@ -1693,7 +1813,7 @@ class DetailedCharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
aa, ab,
RibbonBars(
MeritCommendation.Loser4,
@@ -2050,190 +2170,195 @@ class DetailedCharacterDataTest extends Specification {
Nil, Nil, false,
Some(Cosmetics(true, true, true, true, false))
)
- val char : (Option[Int])=>DetailedCharacterData =
+ val char : Option[Int]=>DetailedCharacterData =
(pad_length : Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)
val inv = InventoryData(
List(
InternalSlot(531, PlanetSideGUID(4202), 0,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(389, PlanetSideGUID(3942), 0,DetailedAmmoBoxData(8, 100))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(389, PlanetSideGUID(3942), 0,DetailedAmmoBoxData(8, 100))))
),
InternalSlot(132, PlanetSideGUID(6924), 1,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(111, PlanetSideGUID(9157), 0, DetailedAmmoBoxData(8, 100))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(111, PlanetSideGUID(9157), 0, DetailedAmmoBoxData(8, 100))))
),
InternalSlot(714, PlanetSideGUID(8498), 2,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(755, PlanetSideGUID(5356), 0, DetailedAmmoBoxData(8, 16))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(755, PlanetSideGUID(5356), 0, DetailedAmmoBoxData(8, 16))))
),
InternalSlot(468, PlanetSideGUID(7198), 4,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(540, PlanetSideGUID(5009), 0, DetailedAmmoBoxData(8, 1))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(5009), 0, DetailedAmmoBoxData(8, 1))))
),
InternalSlot(456, PlanetSideGUID(5374), 5,
- DetailedLockerContainerData(8, Some(InventoryData(List(
- InternalSlot(429, PlanetSideGUID(3021), 0,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(8729), 0, DetailedAmmoBoxData(8, 0))))
- ),
- InternalSlot(838, PlanetSideGUID(8467), 9,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(839, PlanetSideGUID(8603), 0, DetailedAmmoBoxData(8, 5))))
- ),
- InternalSlot(272, PlanetSideGUID(3266), 18, DetailedAmmoBoxData(8, 27)),
- InternalSlot(577, PlanetSideGUID(2934), 22,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(111, PlanetSideGUID(4682), 0, DetailedAmmoBoxData(8, 100))))
- ),
- InternalSlot(839, PlanetSideGUID(3271), 90, DetailedAmmoBoxData(8, 15)),
- InternalSlot(839, PlanetSideGUID(7174), 94, DetailedAmmoBoxData(8, 6)),
- InternalSlot(429, PlanetSideGUID(6084), 98,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(5928), 0, DetailedAmmoBoxData(8, 35))))
- ),
- InternalSlot(462, PlanetSideGUID(5000), 108,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(6277), 0, DetailedAmmoBoxData(8, 150))))
- ),
- InternalSlot(429, PlanetSideGUID(4341), 189,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(7043), 0, DetailedAmmoBoxData(8, 35))))
- ),
- InternalSlot(556, PlanetSideGUID(4168), 198,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(28, PlanetSideGUID(8937), 0, DetailedAmmoBoxData(8, 100))))
- ),
- InternalSlot(272, PlanetSideGUID(3173), 207, DetailedAmmoBoxData(8, 50)),
- InternalSlot(462, PlanetSideGUID(3221), 210,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(4031), 0, DetailedAmmoBoxData(8, 150))))
- ),
- InternalSlot(556, PlanetSideGUID(6853), 280,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(29, PlanetSideGUID(8524), 0, DetailedAmmoBoxData(8, 67))))
- ),
- InternalSlot(556, PlanetSideGUID(4569), 290,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(28, PlanetSideGUID(5584), 0, DetailedAmmoBoxData(8, 100))))
- ),
- InternalSlot(462, PlanetSideGUID(9294), 300,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(3118), 0, DetailedAmmoBoxData(8, 150))))
- ),
- InternalSlot(272, PlanetSideGUID(4759), 387, DetailedAmmoBoxData(8, 50)),
- InternalSlot(462, PlanetSideGUID(7377), 390,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(8155), 0, DetailedAmmoBoxData(8, 150))))
- ),
- InternalSlot(843, PlanetSideGUID(6709), 480, DetailedAmmoBoxData(8, 1)),
- InternalSlot(843, PlanetSideGUID(5276), 484, DetailedAmmoBoxData(8, 1)),
- InternalSlot(843, PlanetSideGUID(7769), 488, DetailedAmmoBoxData(8, 1)),
- InternalSlot(844, PlanetSideGUID(5334), 492, DetailedAmmoBoxData(8, 1)),
- InternalSlot(844, PlanetSideGUID(6219), 496, DetailedAmmoBoxData(8, 1)),
- InternalSlot(842, PlanetSideGUID(7279), 500, DetailedAmmoBoxData(8, 1)),
- InternalSlot(842, PlanetSideGUID(5415), 504, DetailedAmmoBoxData(8, 1)),
- InternalSlot(175, PlanetSideGUID(5741), 540,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5183), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(6208), 541,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5029), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(8589), 542,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(9217), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(8901), 543,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7633), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(8419), 544,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6546), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(4715), 545,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8453), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(3577), 546,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(9202), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(6003), 547,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(3260), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(9140), 548,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(3815),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(4913), 549,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(7222),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(6954), 550,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(2953),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(6405), 551,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(4676),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(8915), 552,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(4018),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(4993), 553,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6775),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(5053), 554,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6418),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(9244), 555,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(3327),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(6292), 556,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6918),0,DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(842, PlanetSideGUID(5357), 558, DetailedAmmoBoxData(8, 1)),
- InternalSlot(844, PlanetSideGUID(4435), 562, DetailedAmmoBoxData(8, 1)),
- InternalSlot(843, PlanetSideGUID(7242), 566, DetailedAmmoBoxData(8, 1)),
- InternalSlot(175, PlanetSideGUID(7330), 570,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4786), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(7415), 571,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6536), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(3949), 572,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7526), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(3805), 573,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7358), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(4493), 574,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6852), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(5762), 575,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(3463), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(3315), 576,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7619), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(324, PlanetSideGUID(6263), 577,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5912), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(4028), 578,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8021), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(2843), 579,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7250), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(9143), 580,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5195), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(5024), 581,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4287), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(6582), 582,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4915), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(6425), 583,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8872), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(468, PlanetSideGUID(4431), 584,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4191), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(8339), 585,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7317), 0, DetailedAmmoBoxData(8, 1))))
- ),
- InternalSlot(175, PlanetSideGUID(3277), 586,
- DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6469), 0, DetailedAmmoBoxData(8, 1))))
+ DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ Some(InventoryData(List(
+ InternalSlot(429, PlanetSideGUID(3021), 0,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(272, PlanetSideGUID(8729), 0, DetailedAmmoBoxData(8, 0))))
+ ),
+ InternalSlot(838, PlanetSideGUID(8467), 9,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(839, PlanetSideGUID(8603), 0, DetailedAmmoBoxData(8, 5))))
+ ),
+ InternalSlot(272, PlanetSideGUID(3266), 18, DetailedAmmoBoxData(8, 27)),
+ InternalSlot(577, PlanetSideGUID(2934), 22,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(111, PlanetSideGUID(4682), 0, DetailedAmmoBoxData(8, 100))))
+ ),
+ InternalSlot(839, PlanetSideGUID(3271), 90, DetailedAmmoBoxData(8, 15)),
+ InternalSlot(839, PlanetSideGUID(7174), 94, DetailedAmmoBoxData(8, 6)),
+ InternalSlot(429, PlanetSideGUID(6084), 98,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(272, PlanetSideGUID(5928), 0, DetailedAmmoBoxData(8, 35))))
+ ),
+ InternalSlot(462, PlanetSideGUID(5000), 108,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(6277), 0, DetailedAmmoBoxData(8, 150))))
+ ),
+ InternalSlot(429, PlanetSideGUID(4341), 189,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(272, PlanetSideGUID(7043), 0, DetailedAmmoBoxData(8, 35))))
+ ),
+ InternalSlot(556, PlanetSideGUID(4168), 198,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(8937), 0, DetailedAmmoBoxData(8, 100))))
+ ),
+ InternalSlot(272, PlanetSideGUID(3173), 207, DetailedAmmoBoxData(8, 50)),
+ InternalSlot(462, PlanetSideGUID(3221), 210,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(4031), 0, DetailedAmmoBoxData(8, 150))))
+ ),
+ InternalSlot(556, PlanetSideGUID(6853), 280,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(29, PlanetSideGUID(8524), 0, DetailedAmmoBoxData(8, 67))))
+ ),
+ InternalSlot(556, PlanetSideGUID(4569), 290,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(5584), 0, DetailedAmmoBoxData(8, 100))))
+ ),
+ InternalSlot(462, PlanetSideGUID(9294), 300,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(3118), 0, DetailedAmmoBoxData(8, 150))))
+ ),
+ InternalSlot(272, PlanetSideGUID(4759), 387, DetailedAmmoBoxData(8, 50)),
+ InternalSlot(462, PlanetSideGUID(7377), 390,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(8155), 0, DetailedAmmoBoxData(8, 150))))
+ ),
+ InternalSlot(843, PlanetSideGUID(6709), 480, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(843, PlanetSideGUID(5276), 484, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(843, PlanetSideGUID(7769), 488, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(844, PlanetSideGUID(5334), 492, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(844, PlanetSideGUID(6219), 496, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(842, PlanetSideGUID(7279), 500, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(842, PlanetSideGUID(5415), 504, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(175, PlanetSideGUID(5741), 540,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(5183), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(6208), 541,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(5029), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(8589), 542,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(9217), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(8901), 543,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7633), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(8419), 544,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(6546), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(4715), 545,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(8453), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(3577), 546,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(9202), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(6003), 547,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(3260), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(9140), 548,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(3815),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(4913), 549,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(7222),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(6954), 550,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(2953),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(6405), 551,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(4676),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(8915), 552,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(4018),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(4993), 553,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(6775),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(5053), 554,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(6418),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(9244), 555,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(3327),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(6292), 556,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540,PlanetSideGUID(6918),0,DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(842, PlanetSideGUID(5357), 558, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(844, PlanetSideGUID(4435), 562, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(843, PlanetSideGUID(7242), 566, DetailedAmmoBoxData(8, 1)),
+ InternalSlot(175, PlanetSideGUID(7330), 570,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(4786), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(7415), 571,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(6536), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(3949), 572,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7526), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(3805), 573,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7358), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(4493), 574,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(6852), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(5762), 575,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(3463), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(3315), 576,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7619), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(324, PlanetSideGUID(6263), 577,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(5912), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(4028), 578,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(8021), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(2843), 579,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7250), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(9143), 580,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(5195), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(5024), 581,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(4287), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(6582), 582,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(4915), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(6425), 583,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(8872), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(468, PlanetSideGUID(4431), 584,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(4191), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(8339), 585,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(7317), 0, DetailedAmmoBoxData(8, 1))))
+ ),
+ InternalSlot(175, PlanetSideGUID(3277), 586,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(6469), 0, DetailedAmmoBoxData(8, 1))))
+ )
)
- ))))
+ )))
),
- InternalSlot(213, PlanetSideGUID(6877), 6, DetailedCommandDetonaterData(4, 8)),
+ InternalSlot(213, PlanetSideGUID(6877), 6, DetailedCommandDetonaterData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)))),
InternalSlot(755, PlanetSideGUID(6227), 9, DetailedAmmoBoxData(8, 16)),
- InternalSlot(728, PlanetSideGUID(7181), 12, DetailedREKData(4, 16)),
+ InternalSlot(728, PlanetSideGUID(7181), 12, DetailedREKData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)), 16)),
InternalSlot(536, PlanetSideGUID(4077), 33, DetailedAmmoBoxData(8, 1)),
InternalSlot(680, PlanetSideGUID(4377), 37,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(681, PlanetSideGUID(8905), 0, DetailedAmmoBoxData(8, 3))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(681, PlanetSideGUID(8905), 0, DetailedAmmoBoxData(8, 3))))
),
- InternalSlot(32, PlanetSideGUID(5523), 39, DetailedACEData(4)),
+ InternalSlot(32, PlanetSideGUID(5523), 39, DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ )),
InternalSlot(673, PlanetSideGUID(3661), 60,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(674, PlanetSideGUID(8542), 0, DetailedAmmoBoxData(8, 3))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(674, PlanetSideGUID(8542), 0, DetailedAmmoBoxData(8, 3))))
)
)
)
@@ -2258,14 +2383,18 @@ class DetailedCharacterDataTest extends Specification {
20,
CharacterVoice.Voice3
),
- false,
- false,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.NC,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Standard,
- None,
- 0,
0,
1176612L,
15,
@@ -2293,7 +2422,7 @@ class DetailedCharacterDataTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
aa, ab,
RibbonBars(
MeritCommendation.DefenseNC5,
@@ -2645,98 +2774,101 @@ class DetailedCharacterDataTest extends Specification {
false,
Some(Cosmetics(true, false, true, true, true))
)
- val char : (Option[Int])=>DetailedCharacterData =
+ val char : Option[Int]=>DetailedCharacterData =
(pad_length : Option[Int]) => DetailedCharacterData(ba, bb(ba.bep, pad_length))(pad_length)
val inv : InventoryData = InventoryData(List(
InternalSlot(411, PlanetSideGUID(10022), 0,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(755, PlanetSideGUID(10023), 0, DetailedAmmoBoxData(8, 8))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(755, PlanetSideGUID(10023), 0, DetailedAmmoBoxData(8, 8))))
),
InternalSlot(845, PlanetSideGUID(5671), 2,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(28, PlanetSideGUID(10019), 0, DetailedAmmoBoxData(8, 25))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(10019), 0, DetailedAmmoBoxData(8, 25))))
),
InternalSlot(468, PlanetSideGUID(3754), 4,
- DetailedWeaponData(2, 8, 0, List(InternalSlot(540, PlanetSideGUID(6693), 0, DetailedAmmoBoxData(8, 1))))
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(540, PlanetSideGUID(6693), 0, DetailedAmmoBoxData(8, 1))))
),
InternalSlot(456, PlanetSideGUID(8199), 5,
- DetailedLockerContainerData(0, Some(InventoryData(List(
- InternalSlot(233, PlanetSideGUID(6315), 0,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(6795), 0, DetailedAmmoBoxData(0, 50))))
- ),
- InternalSlot(233, PlanetSideGUID(4302), 6,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(5511), 0, DetailedAmmoBoxData(0, 50))))
- ),
- InternalSlot(233, PlanetSideGUID(6342), 12,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(7788), 0, DetailedAmmoBoxData(0, 50))))
- ),
- InternalSlot(233, PlanetSideGUID(7392), 18,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(8335), 0, DetailedAmmoBoxData(0, 50))))
- ),
- InternalSlot(233, PlanetSideGUID(4432), 24,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(7020), 0, DetailedAmmoBoxData(0,50))))
- ),
- InternalSlot(716, PlanetSideGUID(4219), 90,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(9275), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(716, PlanetSideGUID(3869), 96,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(6099), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(716, PlanetSideGUID(8954), 102,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(5972), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(233, PlanetSideGUID(7476), 108,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(5704), 0, DetailedAmmoBoxData(0, 50))))
- ),
- InternalSlot(272, PlanetSideGUID(8800), 114, DetailedAmmoBoxData(0, 50)),
- InternalSlot(272, PlanetSideGUID(8649), 177, DetailedAmmoBoxData(0, 50)),
- InternalSlot(716, PlanetSideGUID(7580), 180,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(6734), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(716, PlanetSideGUID(6464), 186,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(4738), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(716, PlanetSideGUID(5408), 192,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(50, PlanetSideGUID(3579), 0, DetailedAmmoBoxData(0, 25))))
- ),
- InternalSlot(556, PlanetSideGUID(8957), 198,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(8223), 0, DetailedAmmoBoxData(0, 100))))
- ),
- InternalSlot(272, PlanetSideGUID(3928), 267, DetailedAmmoBoxData(0, 50)),
- InternalSlot(577, PlanetSideGUID(3403), 279,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(111, PlanetSideGUID(4352), 0, DetailedAmmoBoxData(0, 100))))
- ),
- InternalSlot(577, PlanetSideGUID(8454), 285,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(111, PlanetSideGUID(8724), 0, DetailedAmmoBoxData(0,100))))
- ),
- InternalSlot(272, PlanetSideGUID(3397), 357, DetailedAmmoBoxData(0, 50)),
- InternalSlot(429, PlanetSideGUID(6695), 378,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(272, PlanetSideGUID(6842), 0, DetailedAmmoBoxData(0, 35))))
- ),
- InternalSlot(462, PlanetSideGUID(8304), 420,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(463, PlanetSideGUID(7089), 0, DetailedAmmoBoxData(0, 150))))
- ),
- InternalSlot(462, PlanetSideGUID(3346), 429,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(463, PlanetSideGUID(7557), 0, DetailedAmmoBoxData(0, 150))))
- ),
- InternalSlot(272, PlanetSideGUID(7515), 447, DetailedAmmoBoxData(0, 50)),
- InternalSlot(462, PlanetSideGUID(4622), 510,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(463, PlanetSideGUID(6996), 0, DetailedAmmoBoxData(0, 150))))
- ),
- InternalSlot(462, PlanetSideGUID(6586), 519,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(463, PlanetSideGUID(6870), 0, DetailedAmmoBoxData(0, 150))))
- ),
- InternalSlot(556, PlanetSideGUID(4806), 528,
- DetailedWeaponData(6, 0, 0, List(InternalSlot(28, PlanetSideGUID(8798), 0, DetailedAmmoBoxData(0, 100))))
- ),
- InternalSlot(272, PlanetSideGUID(8429), 537, DetailedAmmoBoxData(0, 50))
- ))))
+ DetailedLockerContainerData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)),
+ Some(InventoryData(List(
+ InternalSlot(233, PlanetSideGUID(6315), 0,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(6795), 0, DetailedAmmoBoxData(0, 50))))
+ ),
+ InternalSlot(233, PlanetSideGUID(4302), 6,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(5511), 0, DetailedAmmoBoxData(0, 50))))
+ ),
+ InternalSlot(233, PlanetSideGUID(6342), 12,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(7788), 0, DetailedAmmoBoxData(0, 50))))
+ ),
+ InternalSlot(233, PlanetSideGUID(7392), 18,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(8335), 0, DetailedAmmoBoxData(0, 50))))
+ ),
+ InternalSlot(233, PlanetSideGUID(4432), 24,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(7020), 0, DetailedAmmoBoxData(0,50))))
+ ),
+ InternalSlot(716, PlanetSideGUID(4219), 90,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(9275), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(716, PlanetSideGUID(3869), 96,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(6099), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(716, PlanetSideGUID(8954), 102,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(5972), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(233, PlanetSideGUID(7476), 108,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(5704), 0, DetailedAmmoBoxData(0, 50))))
+ ),
+ InternalSlot(272, PlanetSideGUID(8800), 114, DetailedAmmoBoxData(0, 50)),
+ InternalSlot(272, PlanetSideGUID(8649), 177, DetailedAmmoBoxData(0, 50)),
+ InternalSlot(716, PlanetSideGUID(7580), 180,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(6734), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(716, PlanetSideGUID(6464), 186,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(4738), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(716, PlanetSideGUID(5408), 192,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(50, PlanetSideGUID(3579), 0, DetailedAmmoBoxData(0, 25))))
+ ),
+ InternalSlot(556, PlanetSideGUID(8957), 198,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(8223), 0, DetailedAmmoBoxData(0, 100))))
+ ),
+ InternalSlot(272, PlanetSideGUID(3928), 267, DetailedAmmoBoxData(0, 50)),
+ InternalSlot(577, PlanetSideGUID(3403), 279,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(111, PlanetSideGUID(4352), 0, DetailedAmmoBoxData(0, 100))))
+ ),
+ InternalSlot(577, PlanetSideGUID(8454), 285,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(111, PlanetSideGUID(8724), 0, DetailedAmmoBoxData(0,100))))
+ ),
+ InternalSlot(272, PlanetSideGUID(3397), 357, DetailedAmmoBoxData(0, 50)),
+ InternalSlot(429, PlanetSideGUID(6695), 378,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(272, PlanetSideGUID(6842), 0, DetailedAmmoBoxData(0, 35))))
+ ),
+ InternalSlot(462, PlanetSideGUID(8304), 420,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(7089), 0, DetailedAmmoBoxData(0, 150))))
+ ),
+ InternalSlot(462, PlanetSideGUID(3346), 429,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(7557), 0, DetailedAmmoBoxData(0, 150))))
+ ),
+ InternalSlot(272, PlanetSideGUID(7515), 447, DetailedAmmoBoxData(0, 50)),
+ InternalSlot(462, PlanetSideGUID(4622), 510,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(6996), 0, DetailedAmmoBoxData(0, 150))))
+ ),
+ InternalSlot(462, PlanetSideGUID(6586), 519,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(463, PlanetSideGUID(6870), 0, DetailedAmmoBoxData(0, 150))))
+ ),
+ InternalSlot(556, PlanetSideGUID(4806), 528,
+ DetailedWeaponData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0)), 0, List(InternalSlot(28, PlanetSideGUID(8798), 0, DetailedAmmoBoxData(0, 100))))
+ ),
+ InternalSlot(272, PlanetSideGUID(8429), 537, DetailedAmmoBoxData(0, 50))
+ ))
+ ))
),
InternalSlot(28, PlanetSideGUID(10018), 6, DetailedAmmoBoxData(8, 50)),
InternalSlot(28, PlanetSideGUID(5612), 9, DetailedAmmoBoxData(8, 50)),
InternalSlot(28, PlanetSideGUID(5128), 12, DetailedAmmoBoxData(8, 50)),
InternalSlot(29, PlanetSideGUID(8363), 33, DetailedAmmoBoxData(8, 50)),
InternalSlot(755, PlanetSideGUID(4090), 36, DetailedAmmoBoxData(8, 16)),
- InternalSlot(728, PlanetSideGUID(10075), 39, DetailedREKData(4, 24))
+ InternalSlot(728, PlanetSideGUID(10075), 39, DetailedREKData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)), 24))
))
val obj = DetailedPlayerData.apply(pos, app, char, inv, DrawnSlot.None)
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedCommandDetonaterDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedCommandDetonaterDataTest.scala
index b1cebb95..f2abe55e 100644
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedCommandDetonaterDataTest.scala
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedCommandDetonaterDataTest.scala
@@ -5,6 +5,7 @@ import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import scodec.bits._
class DetailedCommandDetonaterDataTest extends Specification {
@@ -20,15 +21,29 @@ class DetailedCommandDetonaterDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(3530)
parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[DetailedCommandDetonaterData] mustEqual true
+ data match {
+ case DetailedCommandDetonaterData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
+ faction mustEqual PlanetSideEmpire.VS
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+
+ data.isInstanceOf[DetailedCommandDetonaterData] mustEqual true
case _ =>
ko
}
}
"encode" in {
- val obj = DetailedCommandDetonaterData()
+ val obj = DetailedCommandDetonaterData(CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, None, None, PlanetSideGUID(0)))
val msg = ObjectCreateDetailedMessage(ObjectClass.command_detonater, PlanetSideGUID(8308), ObjectCreateMessageParent(PlanetSideGUID(3530), 0), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_detonater
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedConstructionToolDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedConstructionToolDataTest.scala
new file mode 100644
index 00000000..13ebb06f
--- /dev/null
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedConstructionToolDataTest.scala
@@ -0,0 +1,172 @@
+// Copyright (c) 2019 PSForever
+package game.objectcreatedetailed
+
+import net.psforever.packet._
+import net.psforever.packet.game._
+import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
+import org.specs2.mutable._
+import scodec.bits._
+
+class DetailedConstructionToolDataTest extends Specification {
+ val string_ace = hex"18 87000000 1006 100 C70B 80 8800000200008"
+ val string_boomer_trigger = hex"18 87000000 6304CA8760B 80 C800000200008"
+ val string_telepad = hex"18 97000000 4f00 f3a e301 80 4a680400000200008"
+ val string_telepad_short = hex"18 87000000 2a00 f3a 5d01 89 8000000200008"
+
+ "ACE (detailed)" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_ace).require match {
+ case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
+ len mustEqual 135
+ cls mustEqual ObjectClass.ace
+ guid mustEqual PlanetSideGUID(3015)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(3104)
+ parent.get.slot mustEqual 0
+ data match {
+ case DetailedConstructionToolData(cdata) =>
+ cdata.faction mustEqual PlanetSideEmpire.VS
+ cdata.bops mustEqual false
+ cdata.alternate mustEqual false
+ cdata.v1 mustEqual true
+ cdata.v2.isEmpty mustEqual true
+ cdata.v3 mustEqual false
+ cdata.v4.isEmpty mustEqual true
+ cdata.v5.isEmpty mustEqual true
+ cdata.guid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ )
+ val msg = ObjectCreateDetailedMessage(ObjectClass.ace, PlanetSideGUID(3015), ObjectCreateMessageParent(PlanetSideGUID(3104), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_ace
+ }
+ }
+
+ "Boomer Trigger (detailed)" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_boomer_trigger).require match {
+ case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
+ len mustEqual 135
+ cls mustEqual ObjectClass.boomer_trigger
+ guid mustEqual PlanetSideGUID(2934)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(2502)
+ parent.get.slot mustEqual 0
+ data match {
+ case DetailedConstructionToolData(cdata) =>
+ cdata.faction mustEqual PlanetSideEmpire.NEUTRAL
+ cdata.bops mustEqual false
+ cdata.alternate mustEqual false
+ cdata.v1 mustEqual true
+ cdata.v2.isEmpty mustEqual true
+ cdata.v3 mustEqual false
+ cdata.v4.isEmpty mustEqual true
+ cdata.v5.isEmpty mustEqual true
+ cdata.guid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ )
+ val msg = ObjectCreateDetailedMessage(ObjectClass.boomer_trigger, PlanetSideGUID(2934), ObjectCreateMessageParent(PlanetSideGUID(2502), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_boomer_trigger
+ }
+ }
+
+ "Telepad (detailed)" should {
+ "decode" in {
+ PacketCoding.DecodePacket(string_telepad).require match {
+ case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
+ len mustEqual 151
+ cls mustEqual ObjectClass.router_telepad
+ guid mustEqual PlanetSideGUID(483)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(414)
+ parent.get.slot mustEqual 0
+ data match {
+ case DetailedConstructionToolData(cdata) =>
+ cdata.faction mustEqual PlanetSideEmpire.NC
+ cdata.bops mustEqual false
+ cdata.alternate mustEqual false
+ cdata.v1 mustEqual true
+ cdata.v2.isEmpty mustEqual true
+ cdata.v3 mustEqual false
+ cdata.v4.isEmpty mustEqual true
+ cdata.v5.contains(564) mustEqual true
+ cdata.guid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "decode (short)" in {
+ PacketCoding.DecodePacket(string_telepad_short).require match {
+ case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
+ len mustEqual 135
+ cls mustEqual ObjectClass.router_telepad
+ guid mustEqual PlanetSideGUID(349)
+ parent.isDefined mustEqual true
+ parent.get.guid mustEqual PlanetSideGUID(340)
+ parent.get.slot mustEqual 9
+ data match {
+ case DetailedConstructionToolData(cdata) =>
+ cdata.faction mustEqual PlanetSideEmpire.VS
+ cdata.bops mustEqual false
+ cdata.alternate mustEqual false
+ cdata.v1 mustEqual false
+ cdata.v2.isEmpty mustEqual true
+ cdata.v3 mustEqual false
+ cdata.v4.isEmpty mustEqual true
+ cdata.v5.isEmpty mustEqual true
+ cdata.guid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val obj = DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, Some(564), PlanetSideGUID(0))
+ )
+ val msg = ObjectCreateDetailedMessage(ObjectClass.router_telepad, PlanetSideGUID(483), ObjectCreateMessageParent(PlanetSideGUID(414), 0), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_telepad
+ }
+
+ "encode (short)" in {
+ val obj = DetailedConstructionToolData(CommonFieldData(PlanetSideEmpire.VS))
+ val msg = ObjectCreateDetailedMessage(ObjectClass.router_telepad, PlanetSideGUID(349), ObjectCreateMessageParent(PlanetSideGUID(340), 9), obj)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_telepad_short
+ }
+ }
+}
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedREKDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedREKDataTest.scala
index 5b1ead2d..1ee0b18b 100644
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedREKDataTest.scala
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedREKDataTest.scala
@@ -5,6 +5,7 @@ import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import scodec.bits._
class DetailedREKDataTest extends Specification {
@@ -20,16 +21,28 @@ class DetailedREKDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(75)
parent.get.slot mustEqual 1
- data.isDefined mustEqual true
- data.get.asInstanceOf[DetailedREKData].unk1 mustEqual 4
- data.get.asInstanceOf[DetailedREKData].unk2 mustEqual 0
+ data match {
+ case DetailedREKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk) =>
+ faction mustEqual PlanetSideEmpire.NC
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ unk mustEqual 0
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
"encode" in {
- val obj = DetailedREKData(4)
+ val obj = DetailedREKData(CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))
val msg = ObjectCreateDetailedMessage(ObjectClass.remote_electronics_kit, PlanetSideGUID(1439), ObjectCreateMessageParent(PlanetSideGUID(75), 1), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedTelepadDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedTelepadDataTest.scala
deleted file mode 100644
index 5145b00e..00000000
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedTelepadDataTest.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2017 PSForever
-package game.objectcreatedetailed
-
-import net.psforever.packet._
-import net.psforever.packet.game._
-import net.psforever.packet.game.objectcreate._
-import org.specs2.mutable._
-import scodec.bits._
-
-class DetailedTelepadDataTest extends Specification {
- val string = hex"18 97000000 4f00 f3a e301 80 4a680400000200008"
- val string_short = hex"18 87000000 2a00 f3a 5d01 89 8000000200008"
- //TODO validate the unknown fields before router_guid for testing
-
- "DetailedTelepadData" should {
- "decode" in {
- PacketCoding.DecodePacket(string).require match {
- case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
- len mustEqual 151
- cls mustEqual ObjectClass.router_telepad
- guid mustEqual PlanetSideGUID(483)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(414)
- parent.get.slot mustEqual 0
- data.isDefined mustEqual true
- data.get.isInstanceOf[DetailedTelepadData] mustEqual true
- data.get.asInstanceOf[DetailedTelepadData].router_guid mustEqual Some(PlanetSideGUID(564))
- case _ =>
- ko
- }
- }
-
- "decode (short)" in {
- PacketCoding.DecodePacket(string_short).require match {
- case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
- len mustEqual 135
- cls mustEqual ObjectClass.router_telepad
- guid mustEqual PlanetSideGUID(349)
- parent.isDefined mustEqual true
- parent.get.guid mustEqual PlanetSideGUID(340)
- parent.get.slot mustEqual 9
- data.isDefined mustEqual true
- data.get.isInstanceOf[DetailedTelepadData] mustEqual true
- data.get.asInstanceOf[DetailedTelepadData].router_guid mustEqual None
- case _ =>
- ko
- }
- }
-
- "encode" in {
- val obj = DetailedTelepadData(18, PlanetSideGUID(564))
- val msg = ObjectCreateDetailedMessage(ObjectClass.router_telepad, PlanetSideGUID(483), ObjectCreateMessageParent(PlanetSideGUID(414), 0), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
-
- pkt mustEqual string
- }
-
- "encode (short)" in {
- val obj = DetailedTelepadData(32)
- val msg = ObjectCreateDetailedMessage(ObjectClass.router_telepad, PlanetSideGUID(349), ObjectCreateMessageParent(PlanetSideGUID(340), 9), obj)
- val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
-
- pkt mustEqual string_short
- }
- }
-}
diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala
index 05cb8fd5..9ad972ed 100644
--- a/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala
+++ b/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala
@@ -5,6 +5,7 @@ import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game.{ObjectCreateDetailedMessage, _}
import net.psforever.packet.game.objectcreate._
+import net.psforever.types.PlanetSideEmpire
import scodec.bits._
class DetailedWeaponDataTest extends Specification {
@@ -21,15 +22,33 @@ class DetailedWeaponDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(75)
parent.get.slot mustEqual 2
- data.isDefined mustEqual true
- val obj_wep = data.get.asInstanceOf[DetailedWeaponData]
- obj_wep.unk1 mustEqual 2
- obj_wep.unk2 mustEqual 8
- val obj_ammo = obj_wep.ammo
- obj_ammo.head.objectClass mustEqual 28
- obj_ammo.head.guid mustEqual PlanetSideGUID(1286)
- obj_ammo.head.parentSlot mustEqual 0
- obj_ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 30
+ data match {
+ case DetailedWeaponData(cdata, fmode, ammo, _) =>
+ cdata match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NC
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+
+ fmode mustEqual 0
+
+ ammo.size mustEqual 1
+ ammo.head.objectClass mustEqual 28
+ ammo.head.guid mustEqual PlanetSideGUID(1286)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 30
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -44,27 +63,48 @@ class DetailedWeaponDataTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(75)
parent.get.slot mustEqual 2
- data.isDefined mustEqual true
- val obj_wep = data.get.asInstanceOf[DetailedWeaponData]
- obj_wep.unk1 mustEqual 0
- obj_wep.unk2 mustEqual 8
- val obj_ammo = obj_wep.ammo
- obj_ammo.size mustEqual 2
- obj_ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
- obj_ammo.head.guid mustEqual PlanetSideGUID(1693)
- obj_ammo.head.parentSlot mustEqual 0
- obj_ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 30
- obj_ammo(1).objectClass mustEqual ObjectClass.jammer_cartridge
- obj_ammo(1).guid mustEqual PlanetSideGUID(1564)
- obj_ammo(1).parentSlot mustEqual 1
- obj_ammo(1).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 1
+ data match {
+ case DetailedWeaponData(cdata, fmode, ammo, _) =>
+ cdata match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.TR
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual true
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.isEmpty mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+
+ fmode mustEqual 0
+
+ ammo.size mustEqual 2
+ ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
+ ammo.head.guid mustEqual PlanetSideGUID(1693)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 30
+ ammo(1).objectClass mustEqual ObjectClass.jammer_cartridge
+ ammo(1).guid mustEqual PlanetSideGUID(1564)
+ ammo(1).parentSlot mustEqual 1
+ ammo(1).obj.asInstanceOf[DetailedAmmoBoxData].magazine mustEqual 1
+ case _ =>
+ ko
+ }
case _ =>
ko
}
}
"encode (gauss)" in {
- val obj = DetailedWeaponData(2, 8, ObjectClass.bullet_9mm, PlanetSideGUID(1286), 0, DetailedAmmoBoxData(8, 30))
+ val obj = DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(1286), 0, DetailedAmmoBoxData(8, 30)))
+ )
val msg = ObjectCreateDetailedMessage(ObjectClass.gauss, PlanetSideGUID(1465), ObjectCreateMessageParent(PlanetSideGUID(75), 2), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
@@ -72,11 +112,24 @@ class DetailedWeaponDataTest extends Specification {
}
"encode (punisher)" in {
- val obj = DetailedWeaponData(0, 8, 0,
- DetailedAmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(1693), 0, DetailedAmmoBoxData(8, 30)) ::
- DetailedAmmoBoxData(ObjectClass.jammer_cartridge, PlanetSideGUID(1564), 1, DetailedAmmoBoxData(8, 1)) ::
- Nil
- )(2)
+ val obj = DetailedWeaponData(
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ 0,
+ List(
+ DetailedAmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(1693), 0, DetailedAmmoBoxData(8, 30)),
+ DetailedAmmoBoxData(ObjectClass.jammer_cartridge, PlanetSideGUID(1564), 1, DetailedAmmoBoxData(8, 1))
+ )
+ )
val msg = ObjectCreateDetailedMessage(ObjectClass.punisher, PlanetSideGUID(1703), ObjectCreateMessageParent(PlanetSideGUID(75), 2), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreatevehicle/DestroyedVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/DestroyedVehiclesTest.scala
index 84b243c7..cc7a0055 100644
--- a/common/src/test/scala/game/objectcreatevehicle/DestroyedVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/DestroyedVehiclesTest.scala
@@ -2,8 +2,8 @@
package game.objectcreatevehicle
import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import org.specs2.mutable._
import scodec.bits._
@@ -18,9 +18,8 @@ class DestroyedVehiclesTest extends Specification {
cls mustEqual ObjectClass.ams_destroyed
guid mustEqual PlanetSideGUID(4157)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DestroyedVehicleData] mustEqual true
- val dams = data.get.asInstanceOf[DestroyedVehicleData]
+ data.isInstanceOf[DestroyedVehicleData] mustEqual true
+ val dams = data.asInstanceOf[DestroyedVehicleData]
dams.pos.coord.x mustEqual 3674.0f
dams.pos.coord.y mustEqual 2726.789f
dams.pos.coord.z mustEqual 91.15625f
diff --git a/common/src/test/scala/game/objectcreatevehicle/MountedVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/MountedVehiclesTest.scala
index cbeccc0c..5b73667f 100644
--- a/common/src/test/scala/game/objectcreatevehicle/MountedVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/MountedVehiclesTest.scala
@@ -2,8 +2,8 @@
package game.objectcreatevehicle
import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable._
import scodec.bits._
@@ -22,28 +22,28 @@ class MountedVehiclesTest extends Specification {
len mustEqual 1991
cls mustEqual ObjectClass.mosquito
guid mustEqual PlanetSideGUID(4308)
- parent mustEqual None
+ parent.isEmpty mustEqual true
data match {
- case Some(vdata : VehicleData) =>
+ case vdata : VehicleData =>
vdata.pos.coord mustEqual Vector3(4571.6875f, 5602.1875f, 93)
vdata.pos.orient mustEqual Vector3(11.25f, 2.8125f, 92.8125f)
- vdata.pos.vel mustEqual Some(Vector3(31.71875f, 8.875f, -0.03125f))
- vdata.faction mustEqual PlanetSideEmpire.TR
- vdata.bops mustEqual false
- vdata.destroyed mustEqual false
- vdata.jammered mustEqual false
- vdata.owner_guid mustEqual PlanetSideGUID(3776)
+ vdata.pos.vel.contains(Vector3(31.71875f, 8.875f, -0.03125f)) mustEqual true
+ vdata.data.faction mustEqual PlanetSideEmpire.TR
+ vdata.data.bops mustEqual false
+ vdata.data.alternate mustEqual false
+ vdata.data.v1 mustEqual false
+ vdata.data.v3 mustEqual false
+ vdata.data.v5.isEmpty mustEqual true
+ vdata.data.guid mustEqual PlanetSideGUID(3776)
vdata.health mustEqual 255
vdata.no_mount_points mustEqual false
vdata.driveState mustEqual DriveState.Mobile
vdata.cloak mustEqual false
- vdata.unk1 mustEqual 0
- vdata.unk2 mustEqual false
vdata.unk3 mustEqual false
vdata.unk4 mustEqual false
vdata.unk5 mustEqual false
vdata.unk6 mustEqual false
- vdata.vehicle_format_data mustEqual Some(VariantVehicleData(7))
+ vdata.vehicle_format_data.contains(VariantVehicleData(7)) mustEqual true
vdata.inventory match {
case Some(InventoryData(list)) =>
list.head.objectClass mustEqual ObjectClass.avatar
@@ -54,13 +54,13 @@ class MountedVehiclesTest extends Specification {
app match {
case CharacterAppearanceData(a, b, ribbons) =>
a.app mustEqual BasicCharacterData("ScrawnyRonnie", PlanetSideEmpire.TR, CharacterGender.Male, 5, CharacterVoice.Voice5)
- a.black_ops mustEqual false
- a.jammered mustEqual false
+ a.data.bops mustEqual false
+ a.data.v1 mustEqual false
+ a.data.v2.isEmpty mustEqual true
+ a.data.v3 mustEqual false
+ a.data.v4.isEmpty mustEqual true
+ a.data.v5.isEmpty mustEqual true
a.exosuit mustEqual ExoSuitType.Agile
- a.unk1 mustEqual false
- a.unk2 mustEqual None
- a.unk3 mustEqual None
- a.unk4 mustEqual 0
a.unk5 mustEqual 0
a.unk6 mustEqual 30777081L
a.unk7 mustEqual 1
@@ -77,7 +77,7 @@ class MountedVehiclesTest extends Specification {
b.grenade_state mustEqual GrenadeState.None
b.is_cloaking mustEqual false
b.charging_pose mustEqual false
- b.on_zipline mustEqual None
+ b.on_zipline.isEmpty mustEqual true
b.unk0 mustEqual 316554L
b.unk1 mustEqual false
b.unk2 mustEqual false
@@ -99,7 +99,7 @@ class MountedVehiclesTest extends Specification {
unk mustEqual 7
cr mustEqual 5
implants mustEqual Nil
- cosmetics mustEqual Some(Cosmetics(true, true, true, true, false))
+ cosmetics.contains(Cosmetics(true, true, true, true, false)) mustEqual true
case _ =>
ko
}
@@ -139,14 +139,18 @@ class MountedVehiclesTest extends Specification {
5,
CharacterVoice.Voice5
),
- false,
- false,
- false,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Agile,
- None,
- 0,
0,
30777081L,
1,
@@ -174,7 +178,7 @@ class MountedVehiclesTest extends Specification {
None
)
- val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
+ val app : Int=>CharacterAppearanceData = CharacterAppearanceData(
a, b,
RibbonBars(
MeritCommendation.MarkovVeteran,
@@ -194,16 +198,16 @@ class MountedVehiclesTest extends Specification {
val inv : InventoryData = InventoryData(
List(
InternalSlot(ObjectClass.medicalapplicator, PlanetSideGUID(4201), 0,
- WeaponData(0, 0, 0, List(InternalSlot(ObjectClass.health_canister, PlanetSideGUID(3472), 0, AmmoBoxData(0))))
+ WeaponData(CommonFieldData(PlanetSideEmpire.TR), 0, List(InternalSlot(ObjectClass.health_canister, PlanetSideGUID(3472), 0, CommonFieldData()(false))))
),
InternalSlot(ObjectClass.bank, PlanetSideGUID(2952), 1,
- WeaponData(0, 0, 0, List(InternalSlot(ObjectClass.armor_canister, PlanetSideGUID(3758), 0, AmmoBoxData(0))))
+ WeaponData(CommonFieldData(PlanetSideEmpire.TR), 0, List(InternalSlot(ObjectClass.armor_canister, PlanetSideGUID(3758), 0, CommonFieldData()(false))))
),
InternalSlot(ObjectClass.mini_chaingun, PlanetSideGUID(2929), 2,
- WeaponData(0, 0, 0, List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(3292), 0, AmmoBoxData(0))))
+ WeaponData(CommonFieldData(PlanetSideEmpire.TR), 0, List(InternalSlot(ObjectClass.bullet_9mm, PlanetSideGUID(3292), 0, CommonFieldData()(false))))
),
InternalSlot(ObjectClass.chainblade, PlanetSideGUID(3222), 4,
- WeaponData(0, 0, 0, List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(3100), 0, AmmoBoxData(0))))
+ WeaponData(CommonFieldData(PlanetSideEmpire.TR), 0, List(InternalSlot(ObjectClass.melee_ammo, PlanetSideGUID(3100), 0, CommonFieldData()(false))))
)
)
)
@@ -214,11 +218,7 @@ class MountedVehiclesTest extends Specification {
Vector3(11.25f, 2.8125f, 92.8125f),
Some(Vector3(31.71875f, 8.875f, -0.03125f))
),
- PlanetSideEmpire.TR,
- false, false,
- 0,
- false, false,
- PlanetSideGUID(3776),
+ CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, Some(false), None, PlanetSideGUID(3776)),
false,
255,
false, false,
@@ -230,7 +230,7 @@ class MountedVehiclesTest extends Specification {
List(
InternalSlot(ObjectClass.avatar, PlanetSideGUID(3776), 0, player),
InternalSlot(ObjectClass.rotarychaingun_mosquito, PlanetSideGUID(3602), 1,
- WeaponData(6, 0, 0, List(InternalSlot(ObjectClass.bullet_12mm, PlanetSideGUID(3538), 0, AmmoBoxData(0))))
+ WeaponData(CommonFieldData(), 0, List(InternalSlot(ObjectClass.bullet_12mm, PlanetSideGUID(3538), 0, CommonFieldData()(false))))
)
)
)
diff --git a/common/src/test/scala/game/objectcreatevehicle/NonstandardVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/NonstandardVehiclesTest.scala
index aec38af8..3f31ebf0 100644
--- a/common/src/test/scala/game/objectcreatevehicle/NonstandardVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/NonstandardVehiclesTest.scala
@@ -2,8 +2,8 @@
package game.objectcreatevehicle
import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable._
import scodec.bits._
@@ -21,19 +21,25 @@ class NonstandardVehiclesTest extends Specification {
cls mustEqual ObjectClass.droppod
guid mustEqual PlanetSideGUID(3595)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[DroppodData] mustEqual true
- val droppod = data.get.asInstanceOf[DroppodData]
- droppod.basic.pos.coord.x mustEqual 5108.0f
- droppod.basic.pos.coord.y mustEqual 6164.0f
- droppod.basic.pos.coord.z mustEqual 1023.9844f
- droppod.basic.pos.orient.x mustEqual 0f
- droppod.basic.pos.orient.y mustEqual 0f
- droppod.basic.pos.orient.z mustEqual 90.0f
- droppod.basic.unk mustEqual 2
- droppod.basic.player_guid mustEqual PlanetSideGUID(0)
- droppod.burn mustEqual false
- droppod.health mustEqual 255
+ data match {
+ case DroppodData(basic, burn, health) =>
+ basic.pos.coord mustEqual Vector3(5108.0f, 6164.0f, 1023.9844f)
+ basic.pos.orient mustEqual Vector3.z(90.0f)
+
+ basic.data.faction mustEqual PlanetSideEmpire.VS
+ basic.data.bops mustEqual false
+ basic.data.alternate mustEqual false
+ basic.data.v1 mustEqual true
+ basic.data.v2.isDefined mustEqual false
+ basic.data.v3 mustEqual false
+ basic.data.v5.isDefined mustEqual false
+ basic.data.guid mustEqual PlanetSideGUID(0)
+
+ burn mustEqual false
+ health mustEqual 255
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -48,10 +54,9 @@ class NonstandardVehiclesTest extends Specification {
parent.isDefined mustEqual true
parent.get.guid mustEqual PlanetSideGUID(786)
parent.get.slot mustEqual 3
- data.isDefined mustEqual true
- data.get.isInstanceOf[OrbitalShuttleData] mustEqual true
- data.get.asInstanceOf[OrbitalShuttleData].faction mustEqual PlanetSideEmpire.VS
- data.get.asInstanceOf[OrbitalShuttleData].pos.isDefined mustEqual false
+ data.isInstanceOf[OrbitalShuttleData] mustEqual true
+ data.asInstanceOf[OrbitalShuttleData].faction mustEqual PlanetSideEmpire.VS
+ data.asInstanceOf[OrbitalShuttleData].pos.isDefined mustEqual false
case _ =>
ko
}
@@ -64,9 +69,8 @@ class NonstandardVehiclesTest extends Specification {
cls mustEqual ObjectClass.orbital_shuttle
guid mustEqual PlanetSideGUID(1127)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[OrbitalShuttleData] mustEqual true
- val shuttle = data.get.asInstanceOf[OrbitalShuttleData]
+ data.isInstanceOf[OrbitalShuttleData] mustEqual true
+ val shuttle = data.asInstanceOf[OrbitalShuttleData]
shuttle.faction mustEqual PlanetSideEmpire.VS
shuttle.pos.isDefined mustEqual true
shuttle.pos.get.coord.x mustEqual 5610.0156f
@@ -82,10 +86,9 @@ class NonstandardVehiclesTest extends Specification {
"encode (droppod)" in {
val obj = DroppodData(
- CommonFieldData(
+ CommonFieldDataWithPlacement(
PlacementData(5108.0f, 6164.0f, 1023.9844f, 0f, 0f, 90.0f),
- PlanetSideEmpire.VS,
- 2
+ CommonFieldData(PlanetSideEmpire.VS, 2)
)
)
val msg = ObjectCreateMessage(ObjectClass.droppod, PlanetSideGUID(3595), obj)
diff --git a/common/src/test/scala/game/objectcreatevehicle/NormalVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/NormalVehiclesTest.scala
index 5d537227..5d5dcc4c 100644
--- a/common/src/test/scala/game/objectcreatevehicle/NormalVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/NormalVehiclesTest.scala
@@ -2,8 +2,8 @@
package game.objectcreatevehicle
import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable._
import scodec.bits._
@@ -21,15 +21,14 @@ class NormalVehiclesTest extends Specification {
cls mustEqual ObjectClass.fury
guid mustEqual PlanetSideGUID(413)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val fury = data.get.asInstanceOf[VehicleData]
+ data.isInstanceOf[VehicleData] mustEqual true
+ val fury = data.asInstanceOf[VehicleData]
fury.pos.coord mustEqual Vector3(6531.961f, 1872.1406f,24.734375f)
fury.pos.orient mustEqual Vector3(0, 0, 357.1875f)
- fury.pos.vel mustEqual None
- fury.faction mustEqual PlanetSideEmpire.VS
- fury.unk1 mustEqual 2
- fury.owner_guid mustEqual PlanetSideGUID(0)
+ fury.pos.vel.isEmpty mustEqual true
+ fury.data.faction mustEqual PlanetSideEmpire.VS
+ fury.data.v1 mustEqual true
+ fury.data.guid mustEqual PlanetSideGUID(0)
fury.health mustEqual 255
//
fury.inventory.isDefined mustEqual true
@@ -39,17 +38,40 @@ class NormalVehiclesTest extends Specification {
mounting.guid mustEqual PlanetSideGUID(400)
mounting.parentSlot mustEqual 1
mounting.obj.isInstanceOf[WeaponData] mustEqual true
- val weapon = mounting.obj.asInstanceOf[WeaponData]
- weapon.unk1 mustEqual 0x6
- weapon.unk2 mustEqual 0x8
- weapon.fire_mode mustEqual 0
- weapon.ammo.size mustEqual 1
- val ammo = weapon.ammo.head
- ammo.objectClass mustEqual ObjectClass.hellfire_ammo
- ammo.guid mustEqual PlanetSideGUID(432)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x8
+ mounting.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, ammo, _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.head.objectClass mustEqual ObjectClass.hellfire_ammo
+ ammo.head.guid mustEqual PlanetSideGUID(432)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -62,15 +84,14 @@ class NormalVehiclesTest extends Specification {
cls mustEqual ObjectClass.lightning
guid mustEqual PlanetSideGUID(90)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val lightning = data.get.asInstanceOf[VehicleData]
+ data.isInstanceOf[VehicleData] mustEqual true
+ val lightning = data.asInstanceOf[VehicleData]
lightning.pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
lightning.pos.orient mustEqual Vector3(0, 0, 90)
- lightning.pos.vel mustEqual None
- lightning.faction mustEqual PlanetSideEmpire.VS
- lightning.unk1 mustEqual 2
- lightning.owner_guid mustEqual PlanetSideGUID(0)
+ lightning.pos.vel.isEmpty mustEqual true
+ lightning.data.faction mustEqual PlanetSideEmpire.VS
+ lightning.data.v1 mustEqual true
+ lightning.data.guid mustEqual PlanetSideGUID(0)
lightning.health mustEqual 255
lightning.inventory.isDefined mustEqual true
@@ -79,26 +100,59 @@ class NormalVehiclesTest extends Specification {
mounting.objectClass mustEqual ObjectClass.lightning_weapon_system
mounting.guid mustEqual PlanetSideGUID(91)
mounting.parentSlot mustEqual 1
- mounting.obj.isInstanceOf[WeaponData] mustEqual true
- val weapon = mounting.obj.asInstanceOf[WeaponData]
- weapon.unk1 mustEqual 0x4
- weapon.unk2 mustEqual 0x8
- weapon.fire_mode mustEqual 0
- weapon.ammo.size mustEqual 2
- //0
- var ammo = weapon.ammo.head
- ammo.objectClass mustEqual ObjectClass.bullet_75mm
- ammo.guid mustEqual PlanetSideGUID(92)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x0
- //1
- ammo = weapon.ammo(1)
- ammo.objectClass mustEqual ObjectClass.bullet_25mm
- ammo.guid mustEqual PlanetSideGUID(93)
- ammo.parentSlot mustEqual 1
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x0
+ mounting.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, ammo, _) =>
+ wfaction mustEqual PlanetSideEmpire.VS
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ //0
+ ammo.head.objectClass mustEqual ObjectClass.bullet_75mm
+ ammo.head.guid mustEqual PlanetSideGUID(92)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ //1
+ ammo(1).objectClass mustEqual ObjectClass.bullet_25mm
+ ammo(1).guid mustEqual PlanetSideGUID(93)
+ ammo(1).parentSlot mustEqual 1
+ ammo(1).obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ faction mustEqual PlanetSideEmpire.NEUTRAL
+ bops mustEqual false
+ alternate mustEqual false
+ v1 mustEqual false
+ v2.isEmpty mustEqual true
+ v3 mustEqual false
+ v4.contains(false) mustEqual true
+ v5.isEmpty mustEqual true
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -111,62 +165,104 @@ class NormalVehiclesTest extends Specification {
cls mustEqual ObjectClass.mediumtransport
guid mustEqual PlanetSideGUID(387)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val deliverer = data.get.asInstanceOf[VehicleData]
- deliverer.pos.coord mustEqual Vector3(6531.961f, 1872.1406f, 24.734375f)
- deliverer.pos.orient mustEqual Vector3(0, 0, 357.1875f)
- deliverer.pos.vel mustEqual None
- deliverer.faction mustEqual PlanetSideEmpire.NC
- deliverer.owner_guid mustEqual PlanetSideGUID(0)
- deliverer.health mustEqual 255
- deliverer.driveState mustEqual DriveState.State7
- deliverer.jammered mustEqual false
- deliverer.destroyed mustEqual false
- deliverer.cloak mustEqual false
- deliverer.unk1 mustEqual 2
- deliverer.unk2 mustEqual false
- deliverer.unk3 mustEqual false
- deliverer.unk4 mustEqual false
- deliverer.unk5 mustEqual true
- deliverer.unk6 mustEqual false
- deliverer.vehicle_format_data mustEqual None
- deliverer.inventory.isDefined mustEqual true
- deliverer.inventory.get.contents.size mustEqual 2
- //0
- var mounting = deliverer.inventory.get.contents.head
- mounting.objectClass mustEqual ObjectClass.mediumtransport_weapon_systemA
- mounting.guid mustEqual PlanetSideGUID(383)
- mounting.parentSlot mustEqual 5
- mounting.obj.isInstanceOf[WeaponData] mustEqual true
- var weapon = mounting.obj.asInstanceOf[WeaponData]
- weapon.unk1 mustEqual 0x6
- weapon.unk2 mustEqual 0x8
- weapon.fire_mode mustEqual 0
- weapon.ammo.size mustEqual 1
- var ammo = weapon.ammo.head
- ammo.objectClass mustEqual ObjectClass.bullet_20mm
- ammo.guid mustEqual PlanetSideGUID(420)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x8
- //1
- mounting = deliverer.inventory.get.contents(1)
- mounting.objectClass mustEqual ObjectClass.mediumtransport_weapon_systemB
- mounting.guid mustEqual PlanetSideGUID(556)
- mounting.parentSlot mustEqual 6
- mounting.obj.isInstanceOf[WeaponData] mustEqual true
- weapon = mounting.obj.asInstanceOf[WeaponData]
- weapon.unk1 mustEqual 0x6
- weapon.unk2 mustEqual 0x8
- weapon.fire_mode mustEqual 0
- weapon.ammo.size mustEqual 1
- ammo = weapon.ammo.head
- ammo.objectClass mustEqual ObjectClass.bullet_20mm
- ammo.guid mustEqual PlanetSideGUID(575)
- ammo.parentSlot mustEqual 0
- ammo.obj.isInstanceOf[AmmoBoxData] mustEqual true
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x8
+ data match {
+ case VehicleData(pos, vdata, unk3, health, unk4, _, driveState, unk5, unk6, _, format, Some(InventoryData(inv))) =>
+ pos.coord mustEqual Vector3(6531.961f, 1872.1406f, 24.734375f)
+ pos.orient mustEqual Vector3.z(357.1875f)
+
+ vdata.faction mustEqual PlanetSideEmpire.NC
+ vdata.alternate mustEqual false
+ vdata.v1 mustEqual true
+ vdata.v3 mustEqual false
+ vdata.v5.isEmpty mustEqual true
+ vdata.guid mustEqual PlanetSideGUID(0)
+
+ health mustEqual 255
+ driveState mustEqual DriveState.State7
+ unk3 mustEqual false
+ unk4 mustEqual false
+ unk5 mustEqual true
+ unk6 mustEqual false
+ format.isEmpty mustEqual true
+ //0
+ inv.head.objectClass mustEqual ObjectClass.mediumtransport_weapon_systemA
+ inv.head.guid mustEqual PlanetSideGUID(383)
+ inv.head.parentSlot mustEqual 5
+ inv.head.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.bullet_20mm
+ ammo.guid mustEqual PlanetSideGUID(420)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ //1
+ inv(1).objectClass mustEqual ObjectClass.mediumtransport_weapon_systemB
+ inv(1).guid mustEqual PlanetSideGUID(556)
+ inv(1).parentSlot mustEqual 6
+ inv(1).obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, List(ammo), _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ ammo.objectClass mustEqual ObjectClass.bullet_20mm
+ ammo.guid mustEqual PlanetSideGUID(575)
+ ammo.parentSlot mustEqual 0
+ ammo.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -175,22 +271,26 @@ class NormalVehiclesTest extends Specification {
"encode (fury)" in {
val obj = VehicleData(
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
- PlanetSideEmpire.VS,
- false, false,
- 2,
- false, false,
- PlanetSideGUID(0),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
false,
255,
false, false,
DriveState.Mobile,
false, false, false,
None,
- Some(InventoryData(
+ Some(InventoryData(List(
InventoryItemData(ObjectClass.fury_weapon_systema, PlanetSideGUID(400), 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.hellfire_ammo, PlanetSideGUID(432), 0, AmmoBoxData(0x8))
- ) :: Nil
- ))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2),
+ 0,
+ List(
+ InternalSlot(ObjectClass.hellfire_ammo, PlanetSideGUID(432), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)
+ )
+ )
+ )
+ )
+ )))
)(VehicleFormat.Normal)
val msg = ObjectCreateMessage(ObjectClass.fury, PlanetSideGUID(413), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
@@ -201,22 +301,25 @@ class NormalVehiclesTest extends Specification {
"encode (lightning)" in {
val obj = VehicleData(
PlacementData(3674.8438f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
- PlanetSideEmpire.VS,
- false, false,
- 2,
- false, false,
- PlanetSideGUID(0),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
false,
255,
false, false,
DriveState.Mobile,
false, false, false,
None,
- Some(InventoryData(
+ Some(InventoryData(List(
InventoryItemData(ObjectClass.lightning_weapon_system, PlanetSideGUID(91), 1,
- WeaponData(4, 8, 0, ObjectClass.bullet_75mm, PlanetSideGUID(92), 0, AmmoBoxData(), ObjectClass.bullet_25mm, PlanetSideGUID(93), 1, AmmoBoxData())
- ) :: Nil
- ))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.VS, 2),
+ 0,
+ List(
+ InternalSlot(ObjectClass.bullet_75mm, PlanetSideGUID(92), 0, CommonFieldData()(false)),
+ InternalSlot(ObjectClass.bullet_25mm, PlanetSideGUID(93), 1, CommonFieldData()(false))
+ )
+ )
+ )
+ )))
)(VehicleFormat.Normal)
val msg = ObjectCreateMessage(ObjectClass.lightning, PlanetSideGUID(90), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
@@ -227,25 +330,37 @@ class NormalVehiclesTest extends Specification {
"encode (medium transport)" in {
val obj = VehicleData(
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
- PlanetSideEmpire.NC,
- false, false,
- 2,
- false, false,
- PlanetSideGUID(0),
+ CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
false,
255,
false, false,
DriveState.State7,
true, false, false,
None,
- Some(InventoryData(
+ Some(InventoryData(List(
InventoryItemData(ObjectClass.mediumtransport_weapon_systemA, PlanetSideGUID(383), 5,
- WeaponData(6, 8, ObjectClass.bullet_20mm, PlanetSideGUID(420), 0, AmmoBoxData(8))
- ) ::
- InventoryItemData(ObjectClass.mediumtransport_weapon_systemB, PlanetSideGUID(556), 6,
- WeaponData(6, 8, ObjectClass.bullet_20mm, PlanetSideGUID(575), 0, AmmoBoxData(8))
- ) :: Nil
- ))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2),
+ 0,
+ List(
+ InternalSlot(ObjectClass.bullet_20mm, PlanetSideGUID(420), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)
+ )
+ )
+ )
+ ),
+ InventoryItemData(ObjectClass.mediumtransport_weapon_systemB, PlanetSideGUID(556), 6,
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2),
+ 0,
+ List(
+ InternalSlot(ObjectClass.bullet_20mm, PlanetSideGUID(575), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)
+ )
+ )
+ )
+ )
+ )))
)(VehicleFormat.Normal)
val msg = ObjectCreateMessage(ObjectClass.mediumtransport, PlanetSideGUID(387), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/game/objectcreatevehicle/UtilityVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/UtilityVehiclesTest.scala
index 0c081a16..a7e2e093 100644
--- a/common/src/test/scala/game/objectcreatevehicle/UtilityVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/UtilityVehiclesTest.scala
@@ -2,8 +2,8 @@
package game.objectcreatevehicle
import net.psforever.packet._
-import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate._
+import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable._
import scodec.bits._
@@ -22,20 +22,19 @@ class UtilityVehiclesTest extends Specification {
cls mustEqual ObjectClass.ant
guid mustEqual PlanetSideGUID(380)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val ant = data.get.asInstanceOf[VehicleData]
+ data.isInstanceOf[VehicleData] mustEqual true
+ val ant = data.asInstanceOf[VehicleData]
ant.pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
ant.pos.orient mustEqual Vector3(0, 0, 90)
- ant.faction mustEqual PlanetSideEmpire.VS
- ant.owner_guid mustEqual PlanetSideGUID(0)
+ ant.data.faction mustEqual PlanetSideEmpire.VS
+ ant.data.alternate mustEqual false
+ ant.data.v1 mustEqual true
+ ant.data.v3 mustEqual false
+ ant.data.v5.isEmpty mustEqual true
+ ant.data.guid mustEqual PlanetSideGUID(0)
ant.driveState mustEqual DriveState.Mobile
ant.health mustEqual 255
- ant.jammered mustEqual false
- ant.destroyed mustEqual false
ant.cloak mustEqual false
- ant.unk1 mustEqual 2
- ant.unk2 mustEqual false
ant.unk3 mustEqual false
ant.unk4 mustEqual false
ant.unk5 mustEqual false
@@ -52,22 +51,21 @@ class UtilityVehiclesTest extends Specification {
cls mustEqual ObjectClass.ams
guid mustEqual PlanetSideGUID(4157)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val ams = data.get.asInstanceOf[VehicleData]
+ data.isInstanceOf[VehicleData] mustEqual true
+ val ams = data.asInstanceOf[VehicleData]
ams.pos.coord mustEqual Vector3(3674, 2726.789f, 91.15625f)
ams.pos.orient mustEqual Vector3(0, 0, 90)
ams.pos.vel mustEqual None
- ams.faction mustEqual PlanetSideEmpire.VS
- ams.owner_guid mustEqual PlanetSideGUID(2885)
+ ams.data.faction mustEqual PlanetSideEmpire.VS
+ ams.data.alternate mustEqual false
+ ams.data.v1 mustEqual false
+ ams.data.v3 mustEqual false
+ ams.data.v5.isEmpty mustEqual true
+ ams.data.guid mustEqual PlanetSideGUID(2885)
ams.driveState mustEqual DriveState.Deployed
ams.vehicle_format_data mustEqual Some(UtilityVehicleData(60))
ams.health mustEqual 236
- ams.jammered mustEqual false
- ams.destroyed mustEqual false
ams.cloak mustEqual true
- ams.unk1 mustEqual 0
- ams.unk2 mustEqual false
ams.unk3 mustEqual false
ams.unk4 mustEqual false
ams.unk5 mustEqual false
@@ -78,19 +76,19 @@ class UtilityVehiclesTest extends Specification {
inv.head.objectClass mustEqual ObjectClass.matrix_terminalc
inv.head.guid mustEqual PlanetSideGUID(3663)
inv.head.parentSlot mustEqual 1
- inv.head.obj.isInstanceOf[CommonTerminalData] mustEqual true
+ inv.head.obj.isInstanceOf[CommonFieldData] mustEqual true
inv(1).objectClass mustEqual ObjectClass.ams_respawn_tube
inv(1).guid mustEqual PlanetSideGUID(3638)
inv(1).parentSlot mustEqual 2
- inv(1).obj.isInstanceOf[CommonTerminalData] mustEqual true
+ inv(1).obj.isInstanceOf[CommonFieldData] mustEqual true
inv(2).objectClass mustEqual ObjectClass.order_terminala
inv(2).guid mustEqual PlanetSideGUID(3827)
inv(2).parentSlot mustEqual 3
- inv(2).obj.isInstanceOf[CommonTerminalData] mustEqual true
+ inv(2).obj.isInstanceOf[CommonFieldData] mustEqual true
inv(3).objectClass mustEqual ObjectClass.order_terminalb
inv(3).guid mustEqual PlanetSideGUID(3556)
inv(3).parentSlot mustEqual 4
- inv(3).obj.isInstanceOf[CommonTerminalData] mustEqual true
+ inv(3).obj.isInstanceOf[CommonFieldData] mustEqual true
case _ =>
ko
}
@@ -99,11 +97,7 @@ class UtilityVehiclesTest extends Specification {
"encode (ant)" in {
val obj = VehicleData(
PlacementData(3674.8438f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
- PlanetSideEmpire.VS,
- false, false,
- 2,
- false, false,
- PlanetSideGUID(0),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
false,
255,
false, false,
@@ -121,11 +115,7 @@ class UtilityVehiclesTest extends Specification {
"encode (ams)" in {
val obj = VehicleData(
PlacementData(3674.0f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
- PlanetSideEmpire.VS,
- false, false,
- 0,
- false, false,
- PlanetSideGUID(2885),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, Some(false), None, PlanetSideGUID(2885)),
false,
236,
false, false,
@@ -133,10 +123,10 @@ class UtilityVehiclesTest extends Specification {
false, true, true,
Some(UtilityVehicleData(60)), //what does this mean?
Some(InventoryData(List(
- InternalSlot(ObjectClass.matrix_terminalc, PlanetSideGUID(3663), 1, CommonTerminalData(PlanetSideEmpire.VS)),
- InternalSlot(ObjectClass.ams_respawn_tube, PlanetSideGUID(3638), 2, CommonTerminalData(PlanetSideEmpire.VS)),
- InternalSlot(ObjectClass.order_terminala, PlanetSideGUID(3827), 3, CommonTerminalData(PlanetSideEmpire.VS)),
- InternalSlot(ObjectClass.order_terminalb, PlanetSideGUID(3556), 4, CommonTerminalData(PlanetSideEmpire.VS))
+ InternalSlot(ObjectClass.matrix_terminalc, PlanetSideGUID(3663), 1, CommonFieldData(PlanetSideEmpire.VS)(false)),
+ InternalSlot(ObjectClass.ams_respawn_tube, PlanetSideGUID(3638), 2, CommonFieldData(PlanetSideEmpire.VS)(false)),
+ InternalSlot(ObjectClass.order_terminala, PlanetSideGUID(3827), 3, CommonFieldData(PlanetSideEmpire.VS)(false)),
+ InternalSlot(ObjectClass.order_terminalb, PlanetSideGUID(3556), 4, CommonFieldData(PlanetSideEmpire.VS)(false))
)))
)(VehicleFormat.Utility)
val msg = ObjectCreateMessage(ObjectClass.ams, PlanetSideGUID(4157), obj)
diff --git a/common/src/test/scala/game/objectcreatevehicle/VariantVehiclesTest.scala b/common/src/test/scala/game/objectcreatevehicle/VariantVehiclesTest.scala
index 5924cda1..672945b8 100644
--- a/common/src/test/scala/game/objectcreatevehicle/VariantVehiclesTest.scala
+++ b/common/src/test/scala/game/objectcreatevehicle/VariantVehiclesTest.scala
@@ -19,17 +19,16 @@ class VariantVehiclesTest extends Specification {
cls mustEqual ObjectClass.switchblade
guid mustEqual PlanetSideGUID(418)
parent.isDefined mustEqual false
- data.isDefined mustEqual true
- data.get.isInstanceOf[VehicleData] mustEqual true
- val switchblade = data.get.asInstanceOf[VehicleData]
+ data.isInstanceOf[VehicleData] mustEqual true
+ val switchblade = data.asInstanceOf[VehicleData]
switchblade.pos.coord.x mustEqual 6531.961f
switchblade.pos.coord.y mustEqual 1872.1406f
switchblade.pos.coord.z mustEqual 24.734375f
switchblade.pos.orient.x mustEqual 0f
switchblade.pos.orient.y mustEqual 0f
switchblade.pos.orient.z mustEqual 357.1875f
- switchblade.faction mustEqual PlanetSideEmpire.VS
- switchblade.unk1 mustEqual 2
+ switchblade.data.faction mustEqual PlanetSideEmpire.VS
+ switchblade.data.v1 mustEqual true
switchblade.health mustEqual 255
switchblade.driveState mustEqual DriveState.Mobile
switchblade.inventory.isDefined mustEqual true
@@ -39,21 +38,59 @@ class VariantVehiclesTest extends Specification {
weapon.objectClass mustEqual ObjectClass.scythe
weapon.guid mustEqual PlanetSideGUID(355)
weapon.parentSlot mustEqual 1
- weapon.obj.asInstanceOf[WeaponData].unk1 mustEqual 0x6
- weapon.obj.asInstanceOf[WeaponData].unk2 mustEqual 0x8
- weapon.obj.asInstanceOf[WeaponData].ammo.size mustEqual 2
- //ammo-0
- var ammo = weapon.obj.asInstanceOf[WeaponData].ammo.head
- ammo.objectClass mustEqual ObjectClass.ancient_ammo_vehicle
- ammo.guid mustEqual PlanetSideGUID(366)
- ammo.parentSlot mustEqual 0
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x8
- //ammo-1
- ammo = weapon.obj.asInstanceOf[WeaponData].ammo(1)
- ammo.objectClass mustEqual ObjectClass.ancient_ammo_vehicle
- ammo.guid mustEqual PlanetSideGUID(385)
- ammo.parentSlot mustEqual 1
- ammo.obj.asInstanceOf[AmmoBoxData].unk mustEqual 0x8
+ weapon.obj match {
+ case WeaponData(CommonFieldData(wfaction, wbops, walternate, wv1, wv2, wv3, wv4, wv5, wfguid), fmode, ammo, _) =>
+ wfaction mustEqual PlanetSideEmpire.NEUTRAL
+ wbops mustEqual false
+ walternate mustEqual false
+ wv1 mustEqual true
+ wv2.isEmpty mustEqual true
+ wv3 mustEqual false
+ wv4.isEmpty mustEqual true
+ wv5.isEmpty mustEqual true
+ wfguid mustEqual PlanetSideGUID(0)
+
+ fmode mustEqual 0
+
+ //ammo-0
+ ammo.head.objectClass mustEqual ObjectClass.ancient_ammo_vehicle
+ ammo.head.guid mustEqual PlanetSideGUID(366)
+ ammo.head.parentSlot mustEqual 0
+ ammo.head.obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ //ammo-1
+ ammo(1).objectClass mustEqual ObjectClass.ancient_ammo_vehicle
+ ammo(1).guid mustEqual PlanetSideGUID(385)
+ ammo(1).parentSlot mustEqual 1
+ ammo(1).obj match {
+ case CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid) =>
+ 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
+ fguid mustEqual PlanetSideGUID(0)
+ case _ =>
+ ko
+ }
+ case _ =>
+ ko
+ }
case _ =>
ko
}
@@ -62,22 +99,25 @@ class VariantVehiclesTest extends Specification {
"encode (switchblade)" in {
val obj = VehicleData(
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
- PlanetSideEmpire.VS,
- false, false,
- 2,
- false, false,
- PlanetSideGUID(0),
+ CommonFieldData(PlanetSideEmpire.VS, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)),
false,
255,
false, false,
DriveState.Mobile,
false, false, false,
Some(VariantVehicleData(0)),
- Some(InventoryData(
+ Some(InventoryData(List(
InventoryItemData(ObjectClass.scythe, PlanetSideGUID(355), 1,
- WeaponData(0x6, 0x8, 0, ObjectClass.ancient_ammo_vehicle, PlanetSideGUID(366), 0, AmmoBoxData(0x8), ObjectClass.ancient_ammo_vehicle, PlanetSideGUID(385), 1, AmmoBoxData(0x8))
- ) :: Nil
- ))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(
+ InternalSlot(ObjectClass.ancient_ammo_vehicle, PlanetSideGUID(366), 0, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false)),
+ InternalSlot(ObjectClass.ancient_ammo_vehicle, PlanetSideGUID(385), 1, CommonFieldData(PlanetSideEmpire.NEUTRAL, 2)(false))
+ )
+ )
+ )
+ )))
)(VehicleFormat.Variant)
val msg = ObjectCreateMessage(ObjectClass.switchblade, PlanetSideGUID(418), obj)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
diff --git a/common/src/test/scala/objects/ContainerTest.scala b/common/src/test/scala/objects/ContainerTest.scala
index a34e6693..9d398cee 100644
--- a/common/src/test/scala/objects/ContainerTest.scala
+++ b/common/src/test/scala/objects/ContainerTest.scala
@@ -1,9 +1,9 @@
// Copyright (c) 2017 PSForever
package objects
-import net.psforever.objects.equipment.EquipmentSize
+import net.psforever.objects.equipment.{EquipmentSize, EquipmentSlot}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryEquipmentSlot}
-import net.psforever.objects.{EquipmentSlot, GlobalDefinitions, OffhandEquipmentSlot, Tool}
+import net.psforever.objects.{GlobalDefinitions, OffhandEquipmentSlot, Tool}
import net.psforever.packet.game.PlanetSideGUID
import org.specs2.mutable._
diff --git a/common/src/test/scala/objects/ConverterTest.scala b/common/src/test/scala/objects/ConverterTest.scala
index 4b4d8c1d..1febaac1 100644
--- a/common/src/test/scala/objects/ConverterTest.scala
+++ b/common/src/test/scala/objects/ConverterTest.scala
@@ -25,13 +25,36 @@ class ConverterTest extends Specification {
val obj = AmmoBox(bullet_9mm)
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedAmmoBoxData(8, 50)
+ pkt mustEqual DetailedAmmoBoxData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ obj.Capacity
+ )
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual AmmoBoxData()
+ pkt mustEqual CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ bops = false,
+ alternate = false,
+ false,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
case _ =>
ko
}
@@ -45,13 +68,23 @@ class ConverterTest extends Specification {
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedWeaponData(4,8, Ammo.shotgun_shell.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 12))
+ pkt mustEqual DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(Ammo.shotgun_shell.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 12)))
+ )
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual WeaponData(4,8, 0, Ammo.shotgun_shell.id, PlanetSideGUID(90), 0, AmmoBoxData())
+ pkt mustEqual WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(Ammo.shotgun_shell.id, PlanetSideGUID(90), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)))
+ )
+ )
case _ =>
ko
}
@@ -64,7 +97,9 @@ class ConverterTest extends Specification {
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedWeaponData(4,8, 0,
+ pkt mustEqual DetailedWeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
List(
InternalSlot(Ammo.bullet_9mm.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 30)),
InternalSlot(Ammo.rocket.id, PlanetSideGUID(91), 1, DetailedAmmoBoxData(8, 1))
@@ -75,10 +110,22 @@ class ConverterTest extends Specification {
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual WeaponData(4,8, 0,
+ pkt mustEqual WeaponData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL, //TODO need faction affinity
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
+ 0,
List(
- InternalSlot(Ammo.bullet_9mm.id, PlanetSideGUID(90), 0, AmmoBoxData()),
- InternalSlot(Ammo.rocket.id, PlanetSideGUID(91), 1, AmmoBoxData())
+ InternalSlot(Ammo.bullet_9mm.id, PlanetSideGUID(90), 0, CommonFieldData()(false)),
+ InternalSlot(Ammo.rocket.id, PlanetSideGUID(91), 1, CommonFieldData()(false))
)
)
case _ =>
@@ -100,7 +147,7 @@ class ConverterTest extends Specification {
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual AmmoBoxData()
+ pkt mustEqual CommonFieldData()(false)
case _ =>
ko
}
@@ -112,14 +159,28 @@ class ConverterTest extends Specification {
obj.GUID = PlanetSideGUID(90)
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedACEData(0)
+ pkt mustEqual DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ )
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual ACEData(0,0)
+ pkt mustEqual HandheldData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ )
+ )
case _ =>
ko
}
@@ -135,13 +196,37 @@ class ConverterTest extends Specification {
obj.GUID = PlanetSideGUID(90)
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedREKData(8)
+ pkt mustEqual DetailedREKData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL, //TODO faction affinity
+ false,
+ false,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
+ )
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual REKData(8,0)
+ pkt mustEqual REKData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ false,
+ false,
+ true,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
+ )
case _ =>
ko
}
@@ -154,13 +239,17 @@ class ConverterTest extends Specification {
obj.GUID = PlanetSideGUID(90)
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedBoomerTriggerData()
+ pkt mustEqual DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0))
+ )
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual BoomerTriggerData()
+ pkt mustEqual HandheldData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, None, None, PlanetSideGUID(0))
+ )
case _ =>
ko
}
@@ -173,14 +262,28 @@ class ConverterTest extends Specification {
obj.Router = PlanetSideGUID(1001)
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual TelepadData(0, PlanetSideGUID(1001))
+ pkt mustEqual HandheldData(
+ CommonFieldData(
+ PlanetSideEmpire.NEUTRAL,
+ false,
+ false,
+ false,
+ None,
+ false,
+ None,
+ Some(1001),
+ PlanetSideGUID(0)
+ )
+ )
case _ =>
ko
}
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedTelepadData(0, PlanetSideGUID(1001))
+ pkt mustEqual DetailedConstructionToolData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, Some(1001), PlanetSideGUID(0))
+ )
case _ =>
ko
}
@@ -204,12 +307,19 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual SmallDeployableData(
+ pkt mustEqual CommonFieldDataWithPlacement(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- 0,
- false,
- false
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ false,
+ false,
+ false,
+ None,
+ false,
+ Some(false),
+ None,
+ PlanetSideGUID(0)
+ )
)
case _ =>
ko
@@ -229,17 +339,20 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual SmallTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- 0,
- false,
- false
+ CommonFieldData(PlanetSideEmpire.TR, false, false, false, None, false, Some(true), None, PlanetSideGUID(0))
),
255,
InventoryData(
List(InternalSlot(ObjectClass.spitfire_weapon, PlanetSideGUID(91), 1,
- WeaponData(4, 8, ObjectClass.spitfire_ammo, PlanetSideGUID(92), 0, AmmoBoxData()))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(Ammo.spitfire_ammo.id, PlanetSideGUID(92), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)))
+ ))
+ )
)
)
)
@@ -261,17 +374,20 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual OneMannedFieldTurretData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- 0,
- false,
- false
+ CommonFieldData(PlanetSideEmpire.TR, false, false, true, None, false, Some(false), None, PlanetSideGUID(0))
),
255,
InventoryData(
List(InternalSlot(ObjectClass.energy_gun_tr, PlanetSideGUID(91), 1,
- WeaponData(4, 8, ObjectClass.energy_gun_ammo, PlanetSideGUID(92), 0, AmmoBoxData()))
+ WeaponData(
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
+ 0,
+ List(InternalSlot(Ammo.energy_gun_ammo.id, PlanetSideGUID(92), 0,
+ CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)))
+ ))
+ )
)
)
)
@@ -291,12 +407,19 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual TRAPData(
- SmallDeployableData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- 0,
- false,
- false
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ Some(true),
+ None,
+ PlanetSideGUID(0)
+ )
),
255
)
@@ -316,7 +439,7 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual AegisShieldGeneratorData(
- CommonFieldData(
+ CommonFieldDataWithPlacement(
PlacementData(Vector3.Zero, Vector3.Zero),
PlanetSideEmpire.TR,
0
@@ -339,15 +462,23 @@ class ConverterTest extends Specification {
obj.Health = 1
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual TelepadDeployableData(
+ pkt mustEqual DroppedItemData(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- bops = false,
- destroyed = false,
- unk1 = 2, unk2 = true,
- router_guid = PlanetSideGUID(1001),
- owner_guid = PlanetSideGUID(5001),
- unk3 = 87, unk4 = 12
+ TelepadDeployableData(
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ bops = false,
+ alternate = false,
+ true,
+ None,
+ false,
+ None,
+ Some(1001),
+ PlanetSideGUID(5001)
+ ),
+ unk1 = 87,
+ unk2 = 12
+ )
)
case _ =>
ko
@@ -363,15 +494,23 @@ class ConverterTest extends Specification {
obj.Health = 0
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual TelepadDeployableData(
+ pkt mustEqual DroppedItemData(
PlacementData(Vector3.Zero, Vector3.Zero),
- PlanetSideEmpire.TR,
- bops = false,
- destroyed = true,
- unk1 = 2, unk2 = true,
- router_guid = PlanetSideGUID(1001),
- owner_guid = PlanetSideGUID(0),
- unk3 = 0, unk4 = 6
+ TelepadDeployableData(
+ CommonFieldData(
+ PlanetSideEmpire.TR,
+ bops = false,
+ alternate = true,
+ true,
+ None,
+ false,
+ None,
+ Some(1001),
+ PlanetSideGUID(0)
+ ),
+ unk1 = 0,
+ unk2 = 6
+ )
)
case _ =>
ko
@@ -496,13 +635,13 @@ class ConverterTest extends Specification {
val obj = LockerContainer()
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedLockerContainerData(8, None)
+ pkt mustEqual DetailedLockerContainerData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)), None)
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual LockerContainerData(InventoryData(List.empty))
+ pkt mustEqual LockerContainerData(None)
case _ =>
ko
}
@@ -517,13 +656,13 @@ class ConverterTest extends Specification {
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual DetailedLockerContainerData(8, InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, DetailedREKData(8)) :: Nil)
+ pkt mustEqual DetailedLockerContainerData(8, InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, DetailedREKData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))) :: Nil)
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual LockerContainerData(InventoryData(InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, REKData(8,0)) :: Nil))
+ pkt mustEqual LockerContainerData(InventoryData(InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, REKData(CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, Some(false), None, PlanetSideGUID(0)))) :: Nil))
case _ =>
ko
}
@@ -543,7 +682,7 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual CommonTerminalData(PlanetSideEmpire.NEUTRAL)
+ pkt mustEqual CommonFieldData(PlanetSideEmpire.NEUTRAL)(false)
case _ =>
ko
}
@@ -563,7 +702,7 @@ class ConverterTest extends Specification {
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
- pkt mustEqual CommonTerminalData(PlanetSideEmpire.NEUTRAL)
+ pkt mustEqual CommonFieldData(PlanetSideEmpire.NEUTRAL)(false)
case _ =>
ko
}
diff --git a/common/src/test/scala/objects/EquipmentSlotTest.scala b/common/src/test/scala/objects/EquipmentSlotTest.scala
index 2741225a..08af787d 100644
--- a/common/src/test/scala/objects/EquipmentSlotTest.scala
+++ b/common/src/test/scala/objects/EquipmentSlotTest.scala
@@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever
package objects
-import net.psforever.objects.{EquipmentSlot, OffhandEquipmentSlot, Tool}
-import net.psforever.objects.equipment.EquipmentSize
+import net.psforever.objects.{OffhandEquipmentSlot, Tool}
+import net.psforever.objects.equipment.{EquipmentSize, EquipmentSlot}
import net.psforever.objects.GlobalDefinitions.{beamer, repeater, suppressor}
import org.specs2.mutable._
diff --git a/common/src/test/scala/objects/ExoSuitTest.scala b/common/src/test/scala/objects/ExoSuitTest.scala
index ba9a9123..c7db0ac8 100644
--- a/common/src/test/scala/objects/ExoSuitTest.scala
+++ b/common/src/test/scala/objects/ExoSuitTest.scala
@@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
package objects
-import net.psforever.objects._
+import net.psforever.objects.definition.{ExoSuitDefinition, SpecialExoSuitDefinition}
import net.psforever.objects.equipment._
import net.psforever.objects.inventory.InventoryTile
import net.psforever.types.ExoSuitType
diff --git a/common/src/test/scala/objects/PlayerTest.scala b/common/src/test/scala/objects/PlayerTest.scala
index 4e4d367a..c1471800 100644
--- a/common/src/test/scala/objects/PlayerTest.scala
+++ b/common/src/test/scala/objects/PlayerTest.scala
@@ -3,9 +3,10 @@ package objects
import net.psforever.objects.GlobalDefinitions._
import net.psforever.objects._
-import net.psforever.objects.definition.{ImplantDefinition, SimpleItemDefinition}
+import net.psforever.objects.definition.{ImplantDefinition, SimpleItemDefinition, SpecialExoSuitDefinition}
import net.psforever.objects.equipment.EquipmentSize
import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.packet.game.objectcreate.{Cosmetics, PersonalStyle}
import net.psforever.types._
import org.specs2.mutable._
@@ -521,6 +522,115 @@ class PlayerTest extends Specification {
obj.UsingSpecial != test mustEqual true
}
+ "start with a nonexistent cosmetic state" in {
+ TestPlayer("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5).PersonalStyleFeatures.isEmpty mustEqual true
+ }
+
+ "will not gain cosmetic state if player does not have a certain amount of BEP" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ val (a1, b1) = obj.AddToPersonalStyle(PersonalStyle.Beret)
+ a1.isEmpty mustEqual true
+ b1.isEmpty mustEqual true
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+
+ avatar.BEP = 2286231 //BR24
+ val (a2, b2) = obj.AddToPersonalStyle(PersonalStyle.Beret)
+ a2.isEmpty mustEqual true
+ b2 match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.Beret)
+ case _ =>
+ ko
+ }
+ obj.PersonalStyleFeatures.isEmpty mustEqual false
+ }
+
+ "will lose cosmetic state" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ avatar.BEP = 2286231 //BR24
+ obj.AddToPersonalStyle(PersonalStyle.Beret)
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Beret))) mustEqual true
+ val (a2, b2) = obj.RemoveFromPersonalStyle(PersonalStyle.Beret)
+ a2 match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set(PersonalStyle.Beret)
+ case _ =>
+ ko
+ }
+ b2 match {
+ case Some(c : Cosmetics) =>
+ c.Styles mustEqual Set.empty
+ case _ =>
+ ko
+ }
+ }
+
+ "will not lose cosmetic state if the player doesn't have any cosmetic state to begin with" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ val (a1, b1) = obj.RemoveFromPersonalStyle(PersonalStyle.Beret)
+ a1.isEmpty mustEqual true
+ b1.isEmpty mustEqual true
+ }
+
+ "toggle helmet" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ avatar.BEP = 2286231
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ obj.ToggleHelmet
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.NoHelmet))) mustEqual true
+ obj.ToggleHelmet
+ obj.PersonalStyleFeatures.contains(Cosmetics()) mustEqual true
+ obj.ToggleHelmet
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.NoHelmet))) mustEqual true
+ }
+
+ "toggle suglasses" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ avatar.BEP = 2286231
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ obj.ToggleShades
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Sunglasses))) mustEqual true
+ obj.ToggleShades
+ obj.PersonalStyleFeatures.contains(Cosmetics()) mustEqual true
+ obj.ToggleShades
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Sunglasses))) mustEqual true
+ }
+
+ "toggle earpiece" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ avatar.BEP = 2286231
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ obj.ToggleEarpiece
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Earpiece))) mustEqual true
+ obj.ToggleEarpiece
+ obj.PersonalStyleFeatures.contains(Cosmetics()) mustEqual true
+ obj.ToggleEarpiece
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Earpiece))) mustEqual true
+ }
+
+ "toggle between brimmed cap and beret" in {
+ val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
+ val obj = Player(avatar)
+ avatar.BEP = 2286231
+ obj.PersonalStyleFeatures.isEmpty mustEqual true
+ obj.ToggleHat
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.BrimmedCap))) mustEqual true
+ obj.ToggleHat
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.Beret))) mustEqual true
+ obj.ToggleHat
+ obj.PersonalStyleFeatures.contains(Cosmetics()) mustEqual true
+ obj.ToggleHat
+ obj.PersonalStyleFeatures.contains(Cosmetics(Set(PersonalStyle.BrimmedCap))) mustEqual true
+ }
+
"toString" in {
val obj = TestPlayer("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
obj.toString mustEqual "TR Chord 0/100 0/50"
diff --git a/common/src/test/scala/objects/UtilityTest.scala b/common/src/test/scala/objects/UtilityTest.scala
index 13920cb5..df70ca36 100644
--- a/common/src/test/scala/objects/UtilityTest.scala
+++ b/common/src/test/scala/objects/UtilityTest.scala
@@ -63,7 +63,7 @@ class UtilityTest extends Specification {
obj().Owner = veh //hack
obj().GUID = PlanetSideGUID(1)
- val msg = obj().asInstanceOf[Terminal].Buy(
+ val msg = obj().asInstanceOf[Terminal].Request(
Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)),
ItemTransactionMessage(PlanetSideGUID(853), TransactionType.Buy, 0, "router_telepad", 0, PlanetSideGUID(0))
)
diff --git a/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala
deleted file mode 100644
index 8ea5ae6a..00000000
--- a/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
-import org.specs2.mutable.Specification
-
-class AirVehicleTerminalTest extends Specification {
- "Air_Vehicle_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can buy a reaver ('lightgunship')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
- reply2.vehicle.Definition mustEqual GlobalDefinitions.lightgunship
- reply2.weapons mustEqual Nil
- reply2.inventory.length mustEqual 6
- reply2.inventory.head.obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(1).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(2).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(3).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(4).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(5).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- }
-
- "player can not buy a fake vehicle ('reaver')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "reaver", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/CertTerminalTest.scala b/common/src/test/scala/objects/terminal/CertTerminalTest.scala
deleted file mode 100644
index 5676d327..00000000
--- a/common/src/test/scala/objects/terminal/CertTerminalTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types._
-import org.specs2.mutable.Specification
-
-class CertTerminalTest extends Specification {
- "Cert_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.cert_terminal)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.cert_terminal)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can learn a certification ('medium_assault')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "medium_assault", 0, PlanetSideGUID(0))
- terminal.Request(player, msg) mustEqual Terminal.LearnCertification(CertificationType.MediumAssault)
- }
-
- "player can not learn a fake certification ('juggling')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "juggling", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
-
- "player can forget a certification ('medium_assault')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "medium_assault", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.SellCertification(CertificationType.MediumAssault)
- }
-
- "player can not forget a fake certification ('juggling')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "juggling", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala
deleted file mode 100644
index 3ad3df33..00000000
--- a/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
-import org.specs2.mutable.Specification
-
-class DropshipVehicleTerminalTest extends Specification {
- "Dropship_Vehicle_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can buy a galaxy ('dropship')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "dropship", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
- reply2.vehicle.Definition mustEqual GlobalDefinitions.dropship
- reply2.weapons mustEqual Nil
- reply2.inventory.length mustEqual 12
- reply2.inventory.head.obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(1).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(2).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(3).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(4).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(5).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(6).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(7).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(8).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(9).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(10).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(11).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- }
-
- "player can not buy a fake vehicle ('galaxy')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "galaxy", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala
deleted file mode 100644
index 680d4752..00000000
--- a/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
-import org.specs2.mutable.Specification
-
-class GroundVehicleTerminalTest extends Specification {
- "Ground_Vehicle_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can buy a harasser ('two_man_assault_buggy')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
- reply2.vehicle.Definition mustEqual GlobalDefinitions.two_man_assault_buggy
- reply2.weapons mustEqual Nil
- reply2.inventory.length mustEqual 6
- reply2.inventory.head.obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(1).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(2).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(3).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(4).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(5).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- }
-
- "player can not buy a fake vehicle ('harasser')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/ImplantTerminalInterfaceTest.scala b/common/src/test/scala/objects/terminal/ImplantTerminalInterfaceTest.scala
deleted file mode 100644
index 461fef8f..00000000
--- a/common/src/test/scala/objects/terminal/ImplantTerminalInterfaceTest.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
-import org.specs2.mutable.Specification
-
-class ImplantTerminalInterfaceTest extends Specification {
- "Implant_Terminal_Interface" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can learn an implant ('darklight_vision')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "darklight_vision", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.LearnImplant] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.LearnImplant]
- reply2.implant mustEqual GlobalDefinitions.darklight_vision
- }
-
- "player can not learn a fake implant ('aimbot')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "aimbot", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
-
- "player can surrender an implant ('darklight_vision')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "darklight_vision", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.SellImplant] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.SellImplant]
- reply2.implant mustEqual GlobalDefinitions.darklight_vision
- }
-
- "player can not surrender a fake implant ('aimbot')" in {
- val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "aimbot", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/ImplantTerminalMechTest.scala b/common/src/test/scala/objects/terminal/ImplantTerminalMechTest.scala
index 68e04221..6c324950 100644
--- a/common/src/test/scala/objects/terminal/ImplantTerminalMechTest.scala
+++ b/common/src/test/scala/objects/terminal/ImplantTerminalMechTest.scala
@@ -28,7 +28,7 @@ class ImplantTerminalMechTest extends Specification {
}
}
- "VehicleSpawnPad" should {
+ "Implant_Terminal_Mech" should {
"construct" in {
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
obj.Actor mustEqual ActorRef.noSender
diff --git a/common/src/test/scala/objects/terminal/MatrixTerminalTest.scala b/common/src/test/scala/objects/terminal/MatrixTerminalTest.scala
index 15c3e7e4..b8091205 100644
--- a/common/src/test/scala/objects/terminal/MatrixTerminalTest.scala
+++ b/common/src/test/scala/objects/terminal/MatrixTerminalTest.scala
@@ -1,7 +1,6 @@
// Copyright (c) 2017 PSForever
package objects.terminal
-import akka.actor.ActorRef
import net.psforever.objects.serverobject.terminals.{MatrixTerminalDefinition, Terminal}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@@ -10,59 +9,22 @@ import org.specs2.mutable.Specification
class MatrixTerminalTest extends Specification {
"MatrixTerminal" should {
- "define (a)" in {
+ "define" in {
val a = new MatrixTerminalDefinition(517)
a.ObjectId mustEqual 517
- a.Name mustEqual "matrix_terminala"
}
- "define (b)" in {
- val b = new MatrixTerminalDefinition(518)
- b.ObjectId mustEqual 518
- b.Name mustEqual "matrix_terminalb"
+ "creation" in {
+ Terminal(new MatrixTerminalDefinition(518))
+ ok
}
- "define (c)" in {
- val b = new MatrixTerminalDefinition(519)
- b.ObjectId mustEqual 519
- b.Name mustEqual "matrix_terminalc"
- }
-
- "define (d)" in {
- val b = new MatrixTerminalDefinition(812)
- b.ObjectId mustEqual 812
- b.Name mustEqual "spawn_terminal"
- }
-
- "define (invalid)" in {
- var id : Int = (math.random * Int.MaxValue).toInt
- if(id == 517) {
- id += 3
- }
- else if(id == 518) {
- id += 2
- }
- else if(id == 519 | id == 812) {
- id += 1
- }
-
- new MatrixTerminalDefinition(id) must throwA[IllegalArgumentException]
- }
- }
-
- "Matrix_Terminal" should {
- val terminal = Terminal(GlobalDefinitions.matrix_terminalc)
- terminal.Owner = Vehicle(GlobalDefinitions.quadstealth)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can not buy (anything)" in {
+ "invalid message" in {
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
-
+ val terminal = Terminal(new MatrixTerminalDefinition(519))
+ terminal.Owner = Vehicle(GlobalDefinitions.quadstealth)
+ terminal.Owner.Faction = PlanetSideEmpire.TR
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
}
}
diff --git a/common/src/test/scala/objects/terminal/OrderTerminalABTest.scala b/common/src/test/scala/objects/terminal/OrderTerminalABTest.scala
deleted file mode 100644
index fcdaa498..00000000
--- a/common/src/test/scala/objects/terminal/OrderTerminalABTest.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.serverobject.terminals.{OrderTerminalABDefinition, Terminal}
-import net.psforever.objects.zones.Zone
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types._
-import org.specs2.mutable.Specification
-
-class OrderTerminalABTest extends Specification {
- "OrderTerminalAB" should {
- "define (a)" in {
- val a = new OrderTerminalABDefinition(613)
- a.ObjectId mustEqual 613
- a.Name mustEqual "order_terminala"
- }
-
- "define (b)" in {
- val b = new OrderTerminalABDefinition(614)
- b.ObjectId mustEqual 614
- b.Name mustEqual "order_terminalb"
- }
-
- "define (invalid)" in {
- var id : Int = (math.random * Int.MaxValue).toInt
- if(id == 613) {
- id += 2
- }
- else if(id == 614) {
- id += 1
- }
-
- new OrderTerminalABDefinition(id) must throwA[IllegalArgumentException]
- }
- }
-
- "Order_Terminal" should {
- val terminal = Terminal(GlobalDefinitions.order_terminala)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can buy different armor ('lite_armor')" in {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.BuyExosuit(ExoSuitType.Agile)
- }
-
- "player can buy max armor ('trhev_antiaircraft')" in {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "trhev_antiaircraft", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- //TODO loudout tests
-
- "player can not load max loadout" in {
- val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
- val player = Player(avatar)
- avatar.SaveLoadout(player, "test1", 0)
- player.ExoSuit = ExoSuitType.MAX
- avatar.SaveLoadout(player, "test2", 1)
-
- val msg1 = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Loadout, 4, "", 0, PlanetSideGUID(0))
- terminal.Request(player, msg1) mustEqual Terminal.InfantryLoadout(ExoSuitType.Standard, 0, Nil, Nil)
-
- val msg2 = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Loadout, 4, "", 1, PlanetSideGUID(0))
- terminal.Request(player, msg2) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/common/src/test/scala/objects/terminal/OrderTerminalTest.scala b/common/src/test/scala/objects/terminal/OrderTerminalTest.scala
index ccdc7531..472825a6 100644
--- a/common/src/test/scala/objects/terminal/OrderTerminalTest.scala
+++ b/common/src/test/scala/objects/terminal/OrderTerminalTest.scala
@@ -1,92 +1,95 @@
// Copyright (c) 2017 PSForever
package objects.terminal
-import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
-import net.psforever.objects.{AmmoBox, Avatar, GlobalDefinitions, Player, Tool}
+import net.psforever.objects._
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable.Specification
class OrderTerminalTest extends Specification {
- "Order_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.order_terminal)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
+ val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
+ val player = Player(avatar)
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.order_terminal)
- terminal.Actor mustEqual ActorRef.noSender
+ val building = new Building(0, Zone.Nowhere, StructureType.Building)
+ building.Faction = PlanetSideEmpire.TR
+ val infantryTerminal = Terminal(GlobalDefinitions.order_terminal)
+ infantryTerminal.Owner = building
+
+ "General terminal behavior" should {
+ "player can not buy equipment from the wrong page ('9mmbullet_AP', page 10)" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "9mmbullet_AP", 0, PlanetSideGUID(0))
+
+ infantryTerminal.Request(player, msg) mustEqual Terminal.NoDeal()
}
+ }
+ "Infantry Order Terminal" should {
"player can buy a box of ammunition ('9mmbullet_AP')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "9mmbullet_AP", 0, PlanetSideGUID(0))
- val reply = terminal.Request(player, msg)
+ val reply = infantryTerminal.Request(player, msg)
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
reply2.item.isInstanceOf[AmmoBox] mustEqual true
reply2.item.asInstanceOf[AmmoBox].Definition mustEqual GlobalDefinitions.bullet_9mm_AP
- reply2.item.asInstanceOf[AmmoBox].Capacity mustEqual 50
}
"player can buy a weapon ('suppressor')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "suppressor", 0, PlanetSideGUID(0))
- val reply = terminal.Request(player, msg)
+ val reply = infantryTerminal.Request(player, msg)
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
reply2.item.isInstanceOf[Tool] mustEqual true
reply2.item.asInstanceOf[Tool].Definition mustEqual GlobalDefinitions.suppressor
}
- "player can buy a box of vehicle ammunition ('105mmbullet')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 3, "105mmbullet", 0, PlanetSideGUID(0))
- val reply = terminal.Request(player, msg)
+ "player can buy different armor ('lite_armor')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
+
+ infantryTerminal.Request(player, msg) mustEqual Terminal.BuyExosuit(ExoSuitType.Agile)
+ }
+
+ "player can buy a box of ammunition belonging to a special armor type ('dualcycler_ammo')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "dualcycler_ammo", 0, PlanetSideGUID(0))
+ val reply = infantryTerminal.Request(player, msg)
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
reply2.item.isInstanceOf[AmmoBox] mustEqual true
- reply2.item.asInstanceOf[AmmoBox].Definition mustEqual GlobalDefinitions.bullet_105mm
- reply2.item.asInstanceOf[AmmoBox].Capacity mustEqual 100
+ reply2.item.asInstanceOf[AmmoBox].Definition mustEqual GlobalDefinitions.dualcycler_ammo
}
"player can buy a support tool ('bank')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 2, "bank", 0, PlanetSideGUID(0))
- val reply = terminal.Request(player, msg)
+ val reply = infantryTerminal.Request(player, msg)
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
reply2.item.isInstanceOf[Tool] mustEqual true
reply2.item.asInstanceOf[Tool].Definition mustEqual GlobalDefinitions.bank
}
- "player can buy different armor ('lite_armor')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.BuyExosuit(ExoSuitType.Agile)
+ "player can buy a box of vehicle ammunition ('105mmbullet')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 3, "105mmbullet", 0, PlanetSideGUID(0))
+ val reply = infantryTerminal.Request(player, msg)
+ reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
+ val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
+ reply2.item.isInstanceOf[AmmoBox] mustEqual true
+ reply2.item.asInstanceOf[AmmoBox].Definition mustEqual GlobalDefinitions.bullet_105mm
}
"player can not buy fake equipment ('sabot')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "sabot", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
-
- "player can not buy equipment from the wrong page ('9mmbullet_AP', page 1)" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "9mmbullet_AP", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ infantryTerminal.Request(player, msg) mustEqual Terminal.NoDeal()
}
"player can retrieve an infantry loadout" in {
- val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
- val player2 = Player(avatar)
- player2.ExoSuit = ExoSuitType.Agile
- player2.Slot(0).Equipment = Tool(GlobalDefinitions.beamer)
- player2.Slot(6).Equipment = Tool(GlobalDefinitions.beamer)
- avatar.SaveLoadout(player2, "test", 0)
+ player.ExoSuit = ExoSuitType.Agile
+ player.Slot(0).Equipment = Tool(GlobalDefinitions.beamer)
+ player.Slot(6).Equipment = Tool(GlobalDefinitions.beamer)
+ avatar.SaveLoadout(player, "test", 0)
- val msg = terminal.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 0, PlanetSideGUID(0)))
+ val msg = infantryTerminal.Request(player, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 0, PlanetSideGUID(0)))
msg.isInstanceOf[Terminal.InfantryLoadout] mustEqual true
val loadout = msg.asInstanceOf[Terminal.InfantryLoadout]
loadout.exosuit mustEqual ExoSuitType.Agile
@@ -98,28 +101,120 @@ class OrderTerminalTest extends Specification {
loadout.inventory.head.start mustEqual 6
}
- "player can not retrieve an infantry loadout from the wrong page" in {
- val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
- val player2 = Player(avatar)
- player2.ExoSuit = ExoSuitType.Agile
- player2.Slot(0).Equipment = Tool(GlobalDefinitions.beamer)
- player2.Slot(6).Equipment = Tool(GlobalDefinitions.beamer)
- avatar.SaveLoadout(player2, "test", 0)
-
- val msg = terminal.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 3, "", 0, PlanetSideGUID(0))) //page 3
- msg.isInstanceOf[Terminal.NoDeal] mustEqual true
- }
-
"player can not retrieve an infantry loadout from the wrong line" in {
- val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
- val player2 = Player(avatar)
- player2.ExoSuit = ExoSuitType.Agile
- player2.Slot(0).Equipment = Tool(GlobalDefinitions.beamer)
- player2.Slot(6).Equipment = Tool(GlobalDefinitions.beamer)
- avatar.SaveLoadout(player2, "test", 0)
-
- val msg = terminal.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 1, PlanetSideGUID(0)))
+ val msg = infantryTerminal.Request(player, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 1, PlanetSideGUID(0)))
msg.isInstanceOf[Terminal.NoDeal] mustEqual true
}
}
+
+ "Vehicle Terminal" should {
+ val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
+ terminal.Owner = building
+
+ "player can spawn a vehicle and its default trunk contents" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 46769, "quadassault", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) match {
+ case Terminal.BuyVehicle(vehicle, weapons, trunk) =>
+ vehicle.Definition mustEqual GlobalDefinitions.quadassault
+
+ weapons.size mustEqual 0 //note: vehicles never have custom weapons using the default loadout
+
+ trunk.size mustEqual 4
+ trunk.head.obj.Definition mustEqual GlobalDefinitions.bullet_12mm
+ trunk(1).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
+ trunk(2).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
+ trunk(3).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
+ case _ =>
+ ko
+ }
+ }
+
+ "player can not spawn a fake vehicle ('harasser')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 46769, "harasser", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ }
+
+ "player can retrieve a vehicle loadout" in {
+ val fury = Vehicle(GlobalDefinitions.fury)
+ fury.Slot(30).Equipment = AmmoBox(GlobalDefinitions.hellfire_ammo)
+ avatar.SaveLoadout(fury, "test", 10)
+
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Loadout, 4, "test", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) match {
+ case Terminal.VehicleLoadout(definition, weapons, trunk) =>
+ definition mustEqual GlobalDefinitions.fury
+
+ weapons.size mustEqual 1
+ weapons.head.obj.Definition mustEqual GlobalDefinitions.fury_weapon_systema
+
+ trunk.size mustEqual 1
+ trunk.head.obj.Definition mustEqual GlobalDefinitions.hellfire_ammo
+ case _ =>
+ ko
+ }
+
+ ok
+ }
+ }
+
+ "Certification Terminal" should {
+ val terminal = Terminal(GlobalDefinitions.cert_terminal)
+ terminal.Owner = building
+
+ "player can learn a certification ('medium_assault')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "medium_assault", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) mustEqual Terminal.LearnCertification(CertificationType.MediumAssault)
+ }
+
+ "player can not learn a fake certification ('juggling')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "juggling", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ }
+
+ "player can forget a certification ('medium_assault')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "medium_assault", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) mustEqual Terminal.SellCertification(CertificationType.MediumAssault)
+ }
+
+ "player can not forget a fake certification ('juggling')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "juggling", 0, PlanetSideGUID(0))
+ terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ }
+ }
+
+ "Implant_Terminal_Interface" should {
+ val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
+ terminal.Owner = building
+
+ "player can learn an implant ('darklight_vision')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "darklight_vision", 0, PlanetSideGUID(0))
+
+ val reply = terminal.Request(player, msg)
+ reply.isInstanceOf[Terminal.LearnImplant] mustEqual true
+ val reply2 = reply.asInstanceOf[Terminal.LearnImplant]
+ reply2.implant mustEqual GlobalDefinitions.darklight_vision
+ }
+
+ "player can not learn a fake implant ('aimbot')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "aimbot", 0, PlanetSideGUID(0))
+
+ terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ }
+
+ "player can un-learn an implant ('darklight_vision')" in {
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "darklight_vision", 0, PlanetSideGUID(0))
+
+ val reply = terminal.Request(player, msg)
+ reply.isInstanceOf[Terminal.SellImplant] mustEqual true
+ val reply2 = reply.asInstanceOf[Terminal.SellImplant]
+ reply2.implant mustEqual GlobalDefinitions.darklight_vision
+ }
+
+ "player can not un-learn a fake implant ('aimbot')" in {
+ val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "aimbot", 0, PlanetSideGUID(0))
+
+ terminal.Request(player, msg) mustEqual Terminal.NoDeal()
+ }
+ }
}
diff --git a/common/src/test/scala/objects/terminal/TerminalControlTest.scala b/common/src/test/scala/objects/terminal/TerminalControlTest.scala
index ed5c0e1f..69e192bb 100644
--- a/common/src/test/scala/objects/terminal/TerminalControlTest.scala
+++ b/common/src/test/scala/objects/terminal/TerminalControlTest.scala
@@ -80,7 +80,7 @@ class CertTerminalControl3Test extends ActorTest {
class VehicleTerminalControl1Test extends ActorTest {
"TerminalControl can be used to buy a vehicle ('two_man_assault_buggy')" in {
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.ground_vehicle_terminal, PlanetSideEmpire.TR)
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
+ val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 46769, "two_man_assault_buggy", 0, PlanetSideGUID(0))
terminal.Actor ! Terminal.Request(player, msg)
val reply = receiveOne(Duration.create(500, "ms"))
diff --git a/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala b/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala
deleted file mode 100644
index b6edd741..00000000
--- a/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2017 PSForever
-package objects.terminal
-
-import akka.actor.ActorRef
-import net.psforever.objects.serverobject.structures.{Building, StructureType}
-import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
-import net.psforever.objects.serverobject.terminals.Terminal
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
-import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
-import org.specs2.mutable.Specification
-
-class VehicleTerminalCombinedTest extends Specification {
- "Ground_Vehicle_Terminal" should {
- val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
- val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
- terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
- terminal.Owner.Faction = PlanetSideEmpire.TR
-
- "construct" in {
- val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
- terminal.Actor mustEqual ActorRef.noSender
- }
-
- "player can buy a ground vehicle, the harasser ('two_man_assault_buggy')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
- reply2.vehicle.Definition mustEqual GlobalDefinitions.two_man_assault_buggy
- reply2.weapons mustEqual Nil
- reply2.inventory.length mustEqual 6
- reply2.inventory.head.obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(1).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(2).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(3).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(4).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- reply2.inventory(5).obj.Definition mustEqual GlobalDefinitions.bullet_12mm
- }
-
- "player can buy a flying vehicle, the reaver ('lightgunship')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0))
-
- val reply = terminal.Request(player, msg)
- reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
- val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
- reply2.vehicle.Definition mustEqual GlobalDefinitions.lightgunship
- reply2.weapons mustEqual Nil
- reply2.inventory.length mustEqual 6
- reply2.inventory.head.obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(1).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(2).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(3).obj.Definition mustEqual GlobalDefinitions.reaver_rocket
- reply2.inventory(4).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- reply2.inventory(5).obj.Definition mustEqual GlobalDefinitions.bullet_20mm
- }
-
- "player can not buy a fake vehicle ('harasser')" in {
- val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0))
-
- terminal.Request(player, msg) mustEqual Terminal.NoDeal()
- }
- }
-}
diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala
index 39802b21..4fb1f631 100644
--- a/pslogin/src/main/scala/WorldSessionActor.scala
+++ b/pslogin/src/main/scala/WorldSessionActor.scala
@@ -17,7 +17,7 @@ import net.psforever.objects._
import net.psforever.objects.avatar.{Certification, DeployableToolbox}
import net.psforever.objects.ballistics._
import net.psforever.objects.ce._
-import net.psforever.objects.definition.{ConstructionFireMode, DeployableDefinition, ObjectDefinition, ToolDefinition}
+import net.psforever.objects.definition._
import net.psforever.objects.definition.converter.{CorpseConverter, DestroyedVehicleConverter}
import net.psforever.objects.equipment.{CItem, _}
import net.psforever.objects.loadouts._
@@ -543,7 +543,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
val factionOnContinentChannel = s"${continent.Id}/${player.Faction}"
obj.Owner = None
obj.OwnerName = None
- obj.Faction = PlanetSideEmpire.NEUTRAL
avatar.Deployables.Remove(obj)
UpdateDeployableUIElements(avatar.Deployables.UpdateUIElement(obj.Definition.Item))
localService ! LocalServiceMessage.Deployables(RemoverActor.AddTask(obj, continent))
@@ -1332,20 +1331,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
MountingAction(tplayer, obj, seat_num)
sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, 1000L)) //health of mech
- case Mountable.CanMount(obj : PlanetSideGameObject with WeaponTurret, seat_num) =>
- obj.WeaponControlledFromSeat(seat_num) match {
- case Some(weapon : Tool) =>
- //update mounted weapon belonging to seat
- weapon.AmmoSlots.foreach(slot => {
- //update the magazine(s) in the weapon, specifically
- val magazine = slot.Box
- sendResponse(InventoryStateMessage(magazine.GUID, weapon.GUID, magazine.Capacity.toLong))
- })
- case _ => ; //no weapons to update
- }
- sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health))
- MountingAction(tplayer, obj, seat_num)
-
case Mountable.CanMount(obj : Vehicle, seat_num) =>
val obj_guid : PlanetSideGUID = obj.GUID
val player_guid : PlanetSideGUID = tplayer.GUID
@@ -1384,15 +1369,26 @@ class WorldSessionActor extends Actor with MDCContextAware {
AccessContents(obj)
MountingAction(tplayer, obj, seat_num)
+ case Mountable.CanMount(obj : PlanetSideGameObject with WeaponTurret, seat_num) =>
+ obj.WeaponControlledFromSeat(seat_num) match {
+ case Some(weapon : Tool) =>
+ //update mounted weapon belonging to seat
+ weapon.AmmoSlots.foreach(slot => {
+ //update the magazine(s) in the weapon, specifically
+ val magazine = slot.Box
+ sendResponse(InventoryStateMessage(magazine.GUID, weapon.GUID, magazine.Capacity.toLong))
+ })
+ case _ => ; //no weapons to update
+ }
+ sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health))
+ MountingAction(tplayer, obj, seat_num)
+
case Mountable.CanMount(obj : Mountable, _) =>
log.warn(s"MountVehicleMsg: $obj is some generic mountable object and nothing will happen")
case Mountable.CanDismount(obj : ImplantTerminalMech, seat_num) =>
DismountAction(tplayer, obj, seat_num)
- case Mountable.CanDismount(obj : PlanetSideGameObject with WeaponTurret, seat_num) =>
- DismountAction(tplayer, obj, seat_num)
-
case Mountable.CanDismount(obj : Vehicle, seat_num) =>
val player_guid : PlanetSideGUID = tplayer.GUID
if(player_guid == player.GUID) {
@@ -1405,6 +1401,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, seat_num, true, obj.GUID))
}
+ case Mountable.CanDismount(obj : PlanetSideGameObject with WeaponTurret, seat_num) =>
+ DismountAction(tplayer, obj, seat_num)
+
case Mountable.CanDismount(obj : Mountable, _) =>
log.warn(s"DismountVehicleMsg: $obj is some generic mountable object and nothing will happen")
@@ -1562,6 +1561,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Terminal.BuyEquipment(item) =>
tplayer.Fit(item) match {
case Some(index) =>
+ item.Faction = tplayer.Faction
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, true))
taskResolver ! PutEquipmentInSlot(tplayer, item, index)
case None =>
@@ -1633,10 +1633,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
else {
afterHolsters
}.foreach(entry => {
+ entry.obj.Faction = tplayer.Faction
taskResolver ! PutEquipmentInSlot(tplayer, entry.obj, entry.start)
})
//put items into inventory
afterInventory.foreach(entry => {
+ entry.obj.Faction = tplayer.Faction
taskResolver ! PutEquipmentInSlot(tplayer, entry.obj, entry.start)
})
//drop stuff on ground
@@ -1646,6 +1648,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(item) => List(InventoryItem(item, -1)) //add the item previously in free hand, if any
case None => Nil
}) ++ dropHolsters ++ dropInventory).foreach(entry => {
+ entry.obj.Faction = PlanetSideEmpire.NEUTRAL
continent.Ground ! Zone.Ground.DropItem(entry.obj, pos, orient)
})
lastTerminalOrderFulfillment = true
@@ -1690,6 +1693,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
stow
}
}).foreach({ case InventoryItem(obj, index) =>
+ obj.Faction = tplayer.Faction
taskResolver ! stowEquipment(index, obj)
})
case None =>
@@ -1826,8 +1830,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Terminal.BuyVehicle(vehicle, weapons, trunk) =>
continent.Map.TerminalToSpawnPad.get(msg.terminal_guid.guid) match {
case Some(pad_guid) =>
+ val toFaction = tplayer.Faction
val pad = continent.GUID(pad_guid).get.asInstanceOf[VehicleSpawnPad]
- vehicle.Faction = tplayer.Faction
+ vehicle.Faction = toFaction
vehicle.Continent = continent.Id
vehicle.Position = pad.Position
vehicle.Orientation = pad.Orientation
@@ -1837,6 +1842,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
val index = entry.start
vWeapons.get(index) match {
case Some(slot) =>
+ entry.obj.Faction = toFaction
slot.Equipment = None
slot.Equipment = entry.obj
case None =>
@@ -1847,6 +1853,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
val vTrunk = vehicle.Trunk
vTrunk.Clear()
trunk.foreach(entry => {
+ entry.obj.Faction = toFaction
vTrunk += entry.start -> entry.obj
})
taskResolver ! RegisterNewVehicle(vehicle, pad)
@@ -2419,7 +2426,16 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO if Medkit does not have shortcut, add to a free slot or write over slot 64
sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT))
sendResponse(ChangeShortcutBankMessage(guid, 0))
- //FavoritesMessage
+ //Favorites lists
+ val (inf, veh) = avatar.Loadouts.partition { case (index, _) => index < 10 }
+ inf.foreach {
+ case (index, loadout : InfantryLoadout) =>
+ sendResponse(FavoritesMessage(LoadoutType.Infantry, guid, index, loadout.label, loadout.exosuit.id + loadout.subtype))
+ }
+ veh.foreach {
+ case (index, loadout : VehicleLoadout) =>
+ sendResponse(FavoritesMessage(LoadoutType.Vehicle, guid, index - 10, loadout.label))
+ }
sendResponse(SetChatFilterMessage(ChatChannel.Local, false, ChatChannel.values.toList)) //TODO will not always be "on" like this
deadState = DeadState.Alive
sendResponse(AvatarDeadStateMessage(DeadState.Alive, 0, 0, tplayer.Position, player.Faction, true))
@@ -2472,7 +2488,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO begin temp player character auto-loading; remove later
import net.psforever.objects.GlobalDefinitions._
import net.psforever.types.CertificationType._
- val avatar = Avatar(s"TestCharacter$sessionId", PlanetSideEmpire.VS, CharacterGender.Female, 41, CharacterVoice.Voice1)
+ val faction = PlanetSideEmpire.VS
+ val avatar = Avatar(s"TestCharacter$sessionId", faction, CharacterGender.Female, 41, CharacterVoice.Voice1)
avatar.Certifications += StandardAssault
avatar.Certifications += MediumAssault
avatar.Certifications += StandardExoSuit
@@ -2529,6 +2546,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
player.Slot(36).Equipment = AmmoBox(GlobalDefinitions.StandardPistolAmmo(player.Faction))
player.Slot(39).Equipment = SimpleItem(remote_electronics_kit)
player.Locker.Inventory += 0 -> SimpleItem(remote_electronics_kit)
+ player.Inventory.Items.foreach { _.obj.Faction = faction }
//TODO end temp player character auto-loading
self ! ListAccountCharacters
import scala.concurrent.ExecutionContext.Implicits.global
@@ -3761,7 +3779,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.error("UseItem: expected seated vehicle, but found none")
}
}
- else if(tdef.isInstanceOf[TeleportPadTerminalDefinition]) {
+ else if(tdef == GlobalDefinitions.teleportpad_terminal) {
//explicit request
terminal.Actor ! Terminal.Request(
player,
@@ -5389,15 +5407,18 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
source match {
case obj : Vehicle =>
+ item2.Faction = PlanetSideEmpire.NEUTRAL
vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player_guid, source_guid, index, item2))
case obj : Player =>
+ item2.Faction = obj.Faction
if(source.VisibleSlots.contains(index)) { //item is put in hands
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(player_guid, source_guid, index, item2))
}
else if(obj.isBackpack) { //corpse being given item
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.StowEquipment(player_guid, source_guid, index, item2))
}
- case _ => ;
+ case _ =>
+ item2.Faction = PlanetSideEmpire.NEUTRAL
}
case None => //item2 does not fit; drop on ground
@@ -5437,15 +5458,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
destination match {
case obj : Vehicle =>
+ item.Faction = PlanetSideEmpire.NEUTRAL
vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player_guid, destination_guid, dest, item))
case obj : Player =>
if(destination.VisibleSlots.contains(dest)) { //item is put in hands
+ item.Faction = obj.Faction
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(player_guid, destination_guid, dest, item))
}
else if(obj.isBackpack) { //corpse being given item
+ item.Faction = PlanetSideEmpire.NEUTRAL
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.StowEquipment(player_guid, destination_guid, dest, item))
}
- case _ => ;
+ case _ =>
+ item.Faction = PlanetSideEmpire.NEUTRAL
}
}
@@ -5842,7 +5867,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
/**
* For a given facility structure, configure a client by dispatching the appropriate packets.
- * Pay special attention to the details of `BuildingInfoUpdateMessage` when preparing this packet.
+ * Pay special attention to the details of `BuildingInfoUpdateMessage` when preparing this packet.
+ *
+ * 24 Janurtay 2019:
+ * Manual `BIUM` construction to alleviate player login.
* @see `BuildingInfoUpdateMessage`
* @see `DensityLevelUpdateMessage`
* @param continentNumber the zone id
@@ -5850,7 +5878,31 @@ class WorldSessionActor extends Actor with MDCContextAware {
* @param building the building object
*/
def initFacility(continentNumber : Int, buildingNumber : Int, building : Building) : Unit = {
- building.Actor ! Building.SendMapUpdate(all_clients = false)
+ sendResponse(
+ BuildingInfoUpdateMessage(
+ continentNumber,
+ buildingNumber,
+ ntu_level = 8,
+ is_hacked = false,
+ empire_hack = PlanetSideEmpire.NEUTRAL,
+ hack_time_remaining = 0,
+ building.Faction,
+ unk1 = 0, //!! Field != 0 will cause malformed packet. See class def.
+ unk1x = None,
+ PlanetSideGeneratorState.Normal,
+ spawn_tubes_normal = true,
+ force_dome_active = false,
+ lattice_benefit = 0,
+ cavern_benefit = 0, //!! Field > 0 will cause malformed packet. See class def.
+ unk4 = Nil,
+ unk5 = 0,
+ unk6 = false,
+ unk7 = 8, //!! Field != 8 will cause malformed packet. See class def.
+ unk7x = None,
+ boost_spawn_pain = false,
+ boost_generator_pain = false
+ )
+ )
sendResponse(DensityLevelUpdateMessage(continentNumber, buildingNumber, List(0,0, 0,0, 0,0, 0,0)))
}
@@ -6104,6 +6156,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
obj.Slot(33).Equipment = AmmoBox(bullet_9mm_AP)
obj.Slot(36).Equipment = AmmoBox(StandardPistolAmmo(faction))
obj.Slot(39).Equipment = SimpleItem(remote_electronics_kit)
+ obj.Inventory.Items.foreach { _.obj.Faction = faction }
obj
}
@@ -6599,7 +6652,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO charId should reflect the player more properly
val killerCharId = math.abs(killer.Name.hashCode)
var victimCharId = math.abs(victim.Name.hashCode)
- if(killerCharId == victimCharId && killer.Name != victim.Name) {
+ if(killerCharId == victimCharId && !killer.Name.equals(victim.Name)) {
//odds of hash collision in a populated zone should be close to odds of being struck by lightning
victimCharId = Int.MaxValue - victimCharId + 1
}
@@ -6719,11 +6772,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
* Ownership causes icon to be drawn in yellow to the player (as opposed to a white icon)
* and that signifies a certain level of control over the deployable, at least the ability to quietly deconstruct it.
* Under normal death/respawn cycles while the player is in a given zone,
- * the map icons for owned deployables ramin manipulable to that given user.
- * They do not havwe to be redrawn to stay accurate.
+ * the map icons for owned deployables remain manipulable by that given user.
+ * They do not have to be redrawn to stay accurate.
* Upon leaving a zone, where the icons are erased, and returning back to the zone, where they are drawn again,
* the deployables that a player owned should be restored in terms of their map icon visibility.
- * TThis control can not be recovered, however, until they are updated with the player's globally unique identifier.
+ * This control can not be recovered, however, until they are updated with the player's globally unique identifier.
* Since the player does not need to redraw his own deployable icons each time he respawns,
* but will not possess a valid GUID for that zone until he spawns in it at least once,
* this function swaps out with another after the first spawn in any given zone.
@@ -7298,6 +7351,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO delay or reverse dropping item when player is falling down
item.Position = pos
item.Orientation = Vector3.z(orient.z)
+ item.Faction = PlanetSideEmpire.NEUTRAL
//dropped items rotate towards the user's standing direction
val exclusionId = player.Find(item) match {
//if the item is in our hands ...
@@ -7324,6 +7378,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
def PutItemInHand(item : Equipment) : Boolean = {
player.Fit(item) match {
case Some(slotNum) =>
+ item.Faction = player.Faction
val item_guid = item.GUID
val player_guid = player.GUID
player.Slot(slotNum).Equipment = item
@@ -7509,7 +7564,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
/**
- * For a certain weapon that cna load ammunition, enforce that its magazine is empty.
+ * For a certain weapon that can load ammunition, enforce that its magazine is empty.
* Punctuate that emptiness with a ceasation of weapons fire and a dry fire sound effect.
* @param weapon_guid the weapon (GUID)
* @param tool the weapon (object)
@@ -7590,6 +7645,32 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
}
+ def GetPlayerHackSpeed(obj: PlanetSideServerObject with Hackable): Float = {
+ val playerHackLevel = GetPlayerHackLevel()
+ val timeToHack = obj.HackDuration(playerHackLevel)
+
+ if(timeToHack == 0) {
+ log.warn(s"Player ${player.GUID} tried to hack an object ${obj.GUID} - ${obj.Definition.Name} that they don't have the correct hacking level for")
+ 0f
+ }
+
+ // 250 ms per tick on the hacking progress bar
+ val ticks = (timeToHack * 1000) / 250
+ 100f / ticks
+ }
+
+ def GetPlayerHackLevel(): Int = {
+ if(player.Certifications.contains(CertificationType.ExpertHacking) || player.Certifications.contains(CertificationType.ElectronicsExpert)) {
+ 3
+ } else if(player.Certifications.contains(CertificationType.AdvancedHacking)) {
+ 2
+ } else if (player.Certifications.contains(CertificationType.Hacking)) {
+ 1
+ } else {
+ 0
+ }
+ }
+
def failWithError(error : String) = {
log.error(error)
sendResponse(ConnectionClose())
@@ -7667,13 +7748,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
/**
* `KeepAliveMessage` is a special `PlanetSideGamePacket` that is excluded from being bundled when it is sent to the network.
*
- * The risk of the server getting caught in a state where the packets dispatched to the client are alwaysd bundled is posible.
+ * The risk of the server getting caught in a state where the packets dispatched to the client are always bundled is posible.
* Starting the bundling functionality but forgetting to transition into a state where it is deactivated can lead to this problem.
* No packets except for `KeepAliveMessage` will ever be sent until the ever-accumulating packets overflow.
* To avoid this state, whenever a `KeepAliveMessage` is sent, the packet collector empties its current contents to the network.
- * @see `StartBundlingPackets`
- * `StopBundlingPackets`
- * `clientKeepAlive`
+ * @see `StartBundlingPackets`
+ * @see `StopBundlingPackets`
+ * @see `clientKeepAlive`
* @param cont a `KeepAliveMessage` packet
*/
def sendResponse(cont : KeepAliveMessage) : Unit = {
@@ -7704,32 +7785,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.trace("WORLD SEND RAW: " + pkt)
sendResponse(RawPacket(pkt))
}
-
- def GetPlayerHackSpeed(obj: PlanetSideServerObject with Hackable): Float = {
- val playerHackLevel = GetPlayerHackLevel()
- val timeToHack = obj.HackDuration(playerHackLevel)
-
- if(timeToHack == 0) {
- log.warn(s"Player ${player.GUID} tried to hack an object ${obj.GUID} - ${obj.Definition.Name} that they don't have the correct hacking level for")
- 0f
- }
-
- // 250 ms per tick on the hacking progress bar
- val ticks = (timeToHack * 1000) / 250
- 100f / ticks
- }
-
- def GetPlayerHackLevel(): Int = {
- if(player.Certifications.contains(CertificationType.ExpertHacking) || player.Certifications.contains(CertificationType.ElectronicsExpert)) {
- 3
- } else if(player.Certifications.contains(CertificationType.AdvancedHacking)) {
- 2
- } else if (player.Certifications.contains(CertificationType.Hacking)) {
- 1
- } else {
- 0
- }
- }
}
object WorldSessionActor {
diff --git a/pslogin/src/test/scala/PacketCodingActorTest.scala b/pslogin/src/test/scala/PacketCodingActorTest.scala
index 1628fe5b..5efe312b 100644
--- a/pslogin/src/test/scala/PacketCodingActorTest.scala
+++ b/pslogin/src/test/scala/PacketCodingActorTest.scala
@@ -554,14 +554,18 @@ class PacketCodingActorKTest extends ActorTest {
41,
CharacterVoice.Voice1
),
- false,
- false,
- true,
- None,
- false,
+ CommonFieldData(
+ PlanetSideEmpire.VS,
+ false,
+ false,
+ true,
+ None,
+ false,
+ None,
+ None,
+ PlanetSideGUID(0)
+ ),
ExoSuitType.Standard,
- None,
- 0,
0,
41605313L,
0,