diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
index af3b4a90f..236731264 100644
--- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
+++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
@@ -428,7 +428,7 @@ object GamePacketOpcode extends Enumeration {
case 0x5a => noDecoder(DelayedPathMountMsg)
case 0x5b => noDecoder(OrbitalShuttleTimeMsg)
case 0x5c => noDecoder(AIDamage)
- case 0x5d => game.DeployObjectMessage.decode
+ case 0x5d => noDecoder(DeployObjectMessage)
case 0x5e => noDecoder(FavoritesRequest)
case 0x5f => noDecoder(FavoritesResponse)
@@ -477,7 +477,7 @@ object GamePacketOpcode extends Enumeration {
case 0x83 => noDecoder(SquadWaypointRequest)
case 0x84 => noDecoder(SquadWaypointEvent)
case 0x85 => noDecoder(OffshoreVehicleMessage)
- case 0x86 => noDecoder(ObjectDeployedMessage)
+ case 0x86 => game.ObjectDeployedMessage.decode
case 0x87 => noDecoder(ObjectDeployedCountMessage)
// 0x88
case 0x88 => game.WeaponDelayFireMessage.decode
diff --git a/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala b/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala
deleted file mode 100644
index e18b24429..000000000
--- a/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2017 PSForever
-package net.psforever.packet.game
-
-import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
-import scodec.Codec
-import scodec.codecs._
-import shapeless.{::, HNil}
-
-final case class DeployObjectMessage(guid : PlanetSideGUID,
- str : String,
- unk1 : Long,
- unk2 : Long,
- unk3 : Long)
- extends PlanetSideGamePacket {
- type Packet = DeployObjectMessage
- def opcode = GamePacketOpcode.ObjectDeployedMessage
- def encode = DeployObjectMessage.encode(this)
-}
-
-object DeployObjectMessage extends Marshallable[DeployObjectMessage] {
- implicit val codec : Codec[DeployObjectMessage] = (
- ("object_guid" | PlanetSideGUID.codec) ::
- ("str" | PacketHelpers.encodedString) ::
- ("unk1" | uint32L) ::
- ("unk2" | uint32L) ::
- ("unk3" | uint32L)
- ).xmap[DeployObjectMessage] (
- {
- case guid :: str :: u1 :: u2 :: u3 :: HNil =>
- DeployObjectMessage(guid, str, u1, u2, u3)
- },
- {
- case DeployObjectMessage(guid, str, u1, u2, u3) =>
- //truncate string length to 100 characters; raise no warnings
- val limitedStr : String = if(str.length() > 100) { str.substring(0,100) } else { str }
- guid :: limitedStr :: u1 :: u2 :: u3 :: HNil
- }
- )
-}
diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala
new file mode 100644
index 000000000..007fb1ce1
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala
@@ -0,0 +1,69 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.packet.game
+
+import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
+import scodec.Codec
+import scodec.codecs._
+import shapeless.{::, HNil}
+
+/**
+ * Dispatched by the server when placing deployables to generate a message in the events chat.
+ *
+ * This packet does not actually modify anything in regards to deployables.
+ * It merely generates the message:
+ * `"You have placed x of a possible y thing."`
+ * ... where `x` is the current count of objects of this type that have been deployed;
+ * `y` is the (reported) maximum amount of objects of this type that can be deployed;
+ * and, `thing` is the label for objects of this type.
+ * This text is not directly placed into the message's field but, rather, is a token for language-appropriate descriptive text.
+ * "boomer," for example, is replaced by "Heavy Explosive Mines" in the message for English language.
+ * @param guid na
+ * @param desc descriptive text of what kind of object is being deployed;
+ * matches the `String` description of the object class
+ * @param unk na
+ * @param count the current number of this type of object deployed
+ * @param max the maximum number of this type of object that can be deployed
+ * @see `ObjectClass`
+ */
+final case class ObjectDeployedMessage(guid : PlanetSideGUID,
+ desc : String,
+ unk : Long,
+ count : Long,
+ max : Long)
+ extends PlanetSideGamePacket {
+ type Packet = ObjectDeployedMessage
+ def opcode = GamePacketOpcode.ObjectDeployedMessage
+ def encode = ObjectDeployedMessage.encode(this)
+}
+
+object ObjectDeployedMessage extends Marshallable[ObjectDeployedMessage] {
+ /**
+ * Overloaded constructor for when the guid is not required.
+ * @param desc descriptive text of what kind of object is being deployed
+ * @param unk na
+ * @param count the number of this type of object deployed
+ * @param max the maximum number of this type of object that can be deployed
+ * @return an `ObjectDeployedMessage` object
+ */
+ def apply(desc : String, unk : Long, count : Long, max : Long) : ObjectDeployedMessage =
+ new ObjectDeployedMessage(PlanetSideGUID(0), desc, unk, count, max)
+
+ implicit val codec : Codec[ObjectDeployedMessage] = (
+ ("object_guid" | PlanetSideGUID.codec) ::
+ ("desc" | PacketHelpers.encodedString) ::
+ ("unk" | uint32L) ::
+ ("count" | uint32L) ::
+ ("max" | uint32L)
+ ).xmap[ObjectDeployedMessage] (
+ {
+ case guid :: str :: unk :: cnt ::mx :: HNil =>
+ ObjectDeployedMessage(guid, str, unk, cnt, mx)
+ },
+ {
+ case ObjectDeployedMessage(guid, str, unk, cnt, mx) =>
+ //truncate string length to 100 characters; raise no warnings
+ val limitedStr : String = if(str.length() > 100) { str.substring(0,100) } else { str }
+ guid :: limitedStr :: unk :: cnt :: mx :: HNil
+ }
+ )
+}
diff --git a/common/src/test/scala/game/ObjectDeployedMessageTest.scala b/common/src/test/scala/game/ObjectDeployedMessageTest.scala
new file mode 100644
index 000000000..1910ceea2
--- /dev/null
+++ b/common/src/test/scala/game/ObjectDeployedMessageTest.scala
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 PSForever
+package game
+
+import org.specs2.mutable._
+import net.psforever.packet._
+import net.psforever.packet.game._
+import net.psforever.types.Vector3
+import scodec.bits._
+
+class ObjectDeployedMessageTest extends Specification {
+ val string_boomer = hex"86 000086626F6F6D6572040000000100000019000000"
+
+ "decode" in {
+ PacketCoding.DecodePacket(string_boomer).require match {
+ case ObjectDeployedMessage(guid : PlanetSideGUID, desc : String, unk : Long, count : Long, max : Long) =>
+ guid mustEqual PlanetSideGUID(0)
+ desc mustEqual "boomer"
+ unk mustEqual 4
+ count mustEqual 1
+ max mustEqual 25
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val msg = ObjectDeployedMessage("boomer", 4, 1, 25)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string_boomer
+ }
+}