diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
index 69629b548..35a4cd105 100644
--- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
+++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala
@@ -385,7 +385,7 @@ object GamePacketOpcode extends Enumeration {
case 0x36 => game.PickupItemMessage.decode
case 0x37 => game.DropItemMessage.decode
// 0x38
- case 0x38 => noDecoder(InventoryStateMessage)
+ case 0x38 => game.InventoryStateMessage.decode
case 0x39 => game.ChangeFireStateMessage_Start.decode
case 0x3a => game.ChangeFireStateMessage_Stop.decode
case 0x3b => noDecoder(UnknownMessage59)
diff --git a/common/src/main/scala/net/psforever/packet/game/InventoryStateMessage.scala b/common/src/main/scala/net/psforever/packet/game/InventoryStateMessage.scala
new file mode 100644
index 000000000..1cf24392c
--- /dev/null
+++ b/common/src/main/scala/net/psforever/packet/game/InventoryStateMessage.scala
@@ -0,0 +1,51 @@
+// Copyright (c) 2017 PSForever
+package net.psforever.packet.game
+
+import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
+import scodec.Codec
+import scodec.codecs._
+
+/**
+ * Dispatched by the server to update the value associated with an object in a specific container object.
+ *
+ * The object indicated by `object_guid` must be associated with the inventory (`container_guid`) at the time.
+ * A common use for this packet is to update weapon data when gaining control over that weapon.
+ * For example, before boarding any kind of turret for the first time, it's ammunition component will have exactly one shot.
+ * This shot was established when the turret was first created.
+ * This information would be displayed in the holster icon across the bottom of the GUI while it is mounted.
+ * Furthermore, the mounted player will only fire the turret exactly one time.
+ * This packet can provide the turret with its correct and current amount of ammunition before the player mounts it.
+ * @param object_guid the object being affected
+ * @param unk na;
+ * usually 0
+ * @param container_guid the object in which `object_guid` is contained
+ * @param value an amount with which to update `object_guid`
+ */
+final case class InventoryStateMessage(object_guid : PlanetSideGUID,
+ unk : Int,
+ container_guid : PlanetSideGUID,
+ value : Long)
+ extends PlanetSideGamePacket {
+ type Packet = InventoryStateMessage
+ def opcode = GamePacketOpcode.InventoryStateMessage
+ def encode = InventoryStateMessage.encode(this)
+}
+
+object InventoryStateMessage extends Marshallable[InventoryStateMessage] {
+ /**
+ * Overloaded constructor that ignores the unknown field.
+ * @param object_guid the object being affected
+ * @param container_guid the object in which `object_guid` is contained
+ * @param value an amount with which to update `object_guid`
+ * @return an `InventoryStateMessage` object
+ */
+ def apply(object_guid : PlanetSideGUID, container_guid : PlanetSideGUID, value : Long) : InventoryStateMessage =
+ InventoryStateMessage(object_guid, 0, container_guid, value)
+
+ implicit val codec : Codec[InventoryStateMessage] = (
+ ("object_guid" | PlanetSideGUID.codec) ::
+ ("unk" | uintL(10)) ::
+ ("container_guid" | PlanetSideGUID.codec) ::
+ ("value" | uint32L)
+ ).as[InventoryStateMessage]
+}
diff --git a/common/src/test/scala/game/InventoryStateMessageTest.scala b/common/src/test/scala/game/InventoryStateMessageTest.scala
new file mode 100644
index 000000000..9b0cddfae
--- /dev/null
+++ b/common/src/test/scala/game/InventoryStateMessageTest.scala
@@ -0,0 +1,31 @@
+// Copyright (c) 2017 PSForever
+package game
+
+import org.specs2.mutable._
+import net.psforever.packet._
+import net.psforever.packet.game._
+import scodec.bits._
+
+class InventoryStateMessageTest extends Specification {
+ val string = hex"38 5C0B 00 3C02 B20000000 0"
+
+ "decode" in {
+ PacketCoding.DecodePacket(string).require match {
+ case InventoryStateMessage(object_guid, unk, inv_guid, value) =>
+ object_guid mustEqual PlanetSideGUID(2908)
+ unk mustEqual 0
+ inv_guid mustEqual PlanetSideGUID(2800)
+ value mustEqual 200
+ case _ =>
+ ko
+ }
+ }
+
+ "encode" in {
+ val msg = InventoryStateMessage(PlanetSideGUID(2908), 0, PlanetSideGUID(2800), 200)
+ val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
+
+ pkt mustEqual string
+ }
+}
+