From 62b2c54b67fdeec64f97c3c890a67757e18db01a Mon Sep 17 00:00:00 2001 From: FateJH Date: Mon, 12 Feb 2018 09:59:07 -0500 Subject: [PATCH] added utility filtering so that only valid indexed utilities are assigned GUIDs and are translated into OCM --- .../scala/net/psforever/objects/Vehicle.scala | 18 ++++++++++++++- .../converter/VehicleConverter.scala | 2 +- .../net/psforever/objects/guid/GUIDTask.scala | 4 ++-- .../psforever/objects/vehicles/Utility.scala | 6 +++++ .../test/scala/objects/ConverterTest.scala | 13 ++++++++++- .../src/test/scala/objects/UtilityTest.scala | 2 ++ .../src/test/scala/objects/VehicleTest.scala | 22 ++++++++++++++++++- 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/common/src/main/scala/net/psforever/objects/Vehicle.scala b/common/src/main/scala/net/psforever/objects/Vehicle.scala index 22f87d59e..a5ce3bbdd 100644 --- a/common/src/main/scala/net/psforever/objects/Vehicle.scala +++ b/common/src/main/scala/net/psforever/objects/Vehicle.scala @@ -22,7 +22,15 @@ import scala.annotation.tailrec * Following that are the mounted weapons and other utilities. * Trunk space starts being indexed afterwards.
*
- * To keep it simple, infantry seating, mounted weapons, and utilities are stored separately. + * To keep it simple, infantry seating, mounted weapons, and utilities are stored separately.
+ *
+ * Vehicles maintain a `Map` of `Utility` objects in given index positions. + * Positive indices and zero are considered "represented" and must be assigned a globally unique identifier + * and must be present in the containing vehicle's `ObjectCreateMessage` packet. + * The index is the seat position, reflecting the position in the zero-index inventory. + * Negative indices are expected to be excluded from this conversion. + * The value of the negative index does not have a specific meaning. + * @see `Vehicle.EquipmentUtilities` * @param vehicleDef the vehicle's definition entry'; * stores and unloads pertinent information about the `Vehicle`'s configuration; * used in the initialization process (`loadVehicleDefinition`) @@ -493,6 +501,14 @@ object Vehicle { new Vehicle(vehicleDef) } + /** + * Given a `Map` of `Utility` objects, only return the objects with a positive or zero-index position. + * @return a map of applicable utilities + */ + def EquipmentUtilities(utilities : Map[Int, Utility]) : Map[Int, Utility] = { + utilities.filter({ case(index : Int, _ : Utility) => index > -1 }) + } + /** * Use the `*Definition` that was provided to this object to initialize its fields and settings. * @param vehicle the `Vehicle` being initialized 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 6bef162c4..137ad6c0e 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 @@ -44,7 +44,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() { } protected def MakeUtilities(obj : Vehicle) : List[InventoryItemData.InventoryItem] = { - obj.Utilities.map({ + Vehicle.EquipmentUtilities(obj.Utilities).map({ case(index, utilContainer) => val util = utilContainer() val utilDef = util.Definition 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 95b03452c..95d92bced 100644 --- a/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala +++ b/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala @@ -151,7 +151,7 @@ object GUIDTask { def RegisterVehicle(vehicle : Vehicle)(implicit guid : ActorRef) : TaskResolver.GiveTask = { import net.psforever.objects.inventory.InventoryItem val weaponTasks = vehicle.Weapons.map({ case(_ : Int, entry : EquipmentSlot) => RegisterEquipment(entry.Equipment.get)}).toList - val utilTasks = vehicle.Utilities.map({case (_ : Int, util : Utility) => RegisterObjectTask(util())}).toList + val utilTasks = Vehicle.EquipmentUtilities(vehicle.Utilities).map({case (_ : Int, util : Utility) => RegisterObjectTask(util())}).toList val inventoryTasks = vehicle.Trunk.Items.map({ case((_ : Int, entry : InventoryItem)) => RegisterEquipment(entry.obj)}) TaskResolver.GiveTask(RegisterObjectTask(vehicle).task, weaponTasks ++ utilTasks ++ inventoryTasks) } @@ -255,7 +255,7 @@ object GUIDTask { def UnregisterVehicle(vehicle : Vehicle)(implicit guid : ActorRef) : TaskResolver.GiveTask = { import net.psforever.objects.inventory.InventoryItem val weaponTasks = vehicle.Weapons.map({ case(_ : Int, entry : EquipmentSlot) => UnregisterTool(entry.Equipment.get.asInstanceOf[Tool]) }).toList - val utilTasks = vehicle.Utilities.map({case (_ : Int, util : Utility) => UnregisterObjectTask(util())}).toList + val utilTasks = Vehicle.EquipmentUtilities(vehicle.Utilities).map({case (_ : Int, util : Utility) => UnregisterObjectTask(util())}).toList val inventoryTasks = vehicle.Trunk.Items.map({ case((_ : Int, entry : InventoryItem)) => UnregisterEquipment(entry.obj)}) TaskResolver.GiveTask(UnregisterObjectTask(vehicle).task, weaponTasks ++ utilTasks ++ inventoryTasks) } 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 683b4fc85..5259c3255 100644 --- a/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala +++ b/common/src/main/scala/net/psforever/objects/vehicles/Utility.scala @@ -56,6 +56,12 @@ class Utility(util : UtilityType.Value, vehicle : Vehicle) { * @param context an `ActorContext` potentially useful for the function */ def Setup(implicit context : ActorContext) : Unit = setupFunc(obj, context) + + /** + * Recover the original value used to initialize this object. + * @return the type of the `Amenity` object that was created + */ + def UtilType : UtilityType.Value = util } object Utility { diff --git a/common/src/test/scala/objects/ConverterTest.scala b/common/src/test/scala/objects/ConverterTest.scala index 612637405..723c248f7 100644 --- a/common/src/test/scala/objects/ConverterTest.scala +++ b/common/src/test/scala/objects/ConverterTest.scala @@ -298,7 +298,7 @@ class ConverterTest extends Specification { } "Vehicle" should { - "convert to packet" in { + "convert to packet (1)" in { val hellfire_ammo = AmmoBoxDefinition(Ammo.hellfire_ammo.id) val fury_weapon_systema_def = ToolDefinition(ObjectClass.fury_weapon_systema) @@ -333,5 +333,16 @@ class ConverterTest extends Specification { fury.Definition.Packet.ConstructorData(fury).isSuccess mustEqual true ok //TODO write more of this test } + + "convert to packet (2)" in { + val + ams = Vehicle(GlobalDefinitions.ams) + ams.GUID = PlanetSideGUID(413) + ams.Utilities(3)().GUID = PlanetSideGUID(414) + ams.Utilities(4)().GUID = PlanetSideGUID(415) + + ams.Definition.Packet.ConstructorData(ams).isSuccess mustEqual true + ok //TODO write more of this test + } } } \ No newline at end of file diff --git a/common/src/test/scala/objects/UtilityTest.scala b/common/src/test/scala/objects/UtilityTest.scala index 5ac6740a4..ef78af4bf 100644 --- a/common/src/test/scala/objects/UtilityTest.scala +++ b/common/src/test/scala/objects/UtilityTest.scala @@ -14,6 +14,7 @@ class UtilityTest extends Specification { "Utility" should { "create an order_terminala object" in { val obj = Utility(UtilityType.order_terminala, UtilityTest.vehicle) + obj.UtilType mustEqual UtilityType.order_terminala obj().isInstanceOf[Terminal] mustEqual true obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 613 obj().asInstanceOf[Terminal].Actor == ActorRef.noSender @@ -21,6 +22,7 @@ class UtilityTest extends Specification { "create an order_terminalb object" in { val obj = Utility(UtilityType.order_terminalb, UtilityTest.vehicle) + obj.UtilType mustEqual UtilityType.order_terminalb obj().isInstanceOf[Terminal] mustEqual true obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 614 obj().asInstanceOf[Terminal].Actor == ActorRef.noSender diff --git a/common/src/test/scala/objects/VehicleTest.scala b/common/src/test/scala/objects/VehicleTest.scala index 1bd7abfaf..e7e6f2e39 100644 --- a/common/src/test/scala/objects/VehicleTest.scala +++ b/common/src/test/scala/objects/VehicleTest.scala @@ -3,7 +3,7 @@ package objects import akka.actor.Props import net.psforever.objects.{GlobalDefinitions, Player, Vehicle} -import net.psforever.objects.definition.SeatDefinition +import net.psforever.objects.definition.{SeatDefinition, VehicleDefinition} import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vehicles._ import net.psforever.packet.game.PlanetSideGUID @@ -256,6 +256,26 @@ class VehicleTest extends Specification { harasser_vehicle.WeaponControlledFromSeat(0) mustEqual None harasser_vehicle.WeaponControlledFromSeat(1) mustEqual chaingun_p } + + "can filter utilities with indices that are natural numbers" in { + val objDef = VehicleDefinition(1) + objDef.Utilities += -1 -> UtilityType.order_terminala + objDef.Utilities += 0 -> UtilityType.order_terminalb + objDef.Utilities += 2 -> UtilityType.order_terminalb + val obj = Vehicle(objDef) + + obj.Utilities.size mustEqual 3 + obj.Utilities(-1).UtilType mustEqual UtilityType.order_terminala + obj.Utilities(0).UtilType mustEqual UtilityType.order_terminalb + obj.Utilities.get(1) mustEqual None + obj.Utilities(2).UtilType mustEqual UtilityType.order_terminalb + + val filteredMap = Vehicle.EquipmentUtilities(obj.Utilities) + filteredMap.size mustEqual 2 + filteredMap.get(-1) mustEqual None + filteredMap(0).UtilType mustEqual UtilityType.order_terminalb + filteredMap(2).UtilType mustEqual UtilityType.order_terminalb + } } }