diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 45b50dfb2..1ee7ca6fb 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -367,7 +367,7 @@ object GamePacketOpcode extends Enumeration { case 0x27 => noDecoder(ObjectDetachMessage) // 0x28 case 0x28 => game.CreateShortcutMessage.decode - case 0x29 => noDecoder(ChangeShortcutBankMessage) + case 0x29 => game.ChangeShortcutBankMessage.decode case 0x2a => noDecoder(ObjectAttachMessage) case 0x2b => noDecoder(UnknownMessage43) case 0x2c => noDecoder(PlanetsideAttributeMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/ChangeShortcutBankMessage.scala b/common/src/main/scala/net/psforever/packet/game/ChangeShortcutBankMessage.scala new file mode 100644 index 000000000..c2a097bba --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/ChangeShortcutBankMessage.scala @@ -0,0 +1,35 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** + * Switch the set of shortcuts displayed on the HUD's hotbar.
+ *
+ * The hotbar contains eight slots for user shortcuts - medkits, implants, and text macros. + * Next to the first slot are up and down arrow buttons with a number. + * By progressing through the options available from the arrows, eight sets of eight shortcut slots are revealed. + * Which set is visible determines the effect of the respective binding keys (the Function keys) for the hotbar. + * Each set is called a "bank," obviously.
+ *
+ * This packet coordinates the bank number both as an upstream and as a downstream packet. + * @param player_guid the player + * @param bank the shortcut bank (zero-indexed); + * 0-7 are the valid banks + */ +final case class ChangeShortcutBankMessage(player_guid : PlanetSideGUID, + bank : Int) + extends PlanetSideGamePacket { + type Packet = ChangeShortcutBankMessage + def opcode = GamePacketOpcode.ChangeShortcutBankMessage + def encode = ChangeShortcutBankMessage.encode(this) +} + +object ChangeShortcutBankMessage extends Marshallable[ChangeShortcutBankMessage] { + implicit val codec : Codec[ChangeShortcutBankMessage] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("bank" | uint4L) + ).as[ChangeShortcutBankMessage] +} diff --git a/common/src/main/scala/net/psforever/packet/game/CreateShortcutMessage.scala b/common/src/main/scala/net/psforever/packet/game/CreateShortcutMessage.scala index cfed14927..0232394b3 100644 --- a/common/src/main/scala/net/psforever/packet/game/CreateShortcutMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/CreateShortcutMessage.scala @@ -57,7 +57,13 @@ final case class Shortcut(purpose : Int, *
* When `addShortcut` is `true`, the provided `Shortcut` will be defined and attached to the respective hotbar slot indicated by `slot`. * If it is `false`, the given `slot` will be unbound. - * Nothing happens if the `slot` selection is invalid. + * Nothing happens if the `slot` selection is invalid.
+ *
+ * This packet coordinates the shortcut both as an upstream and as a downstream packet, leaning heavily towards the latter. + * An interesting application is that, if the user does not already have a medkit or a medkit shortcut; + * but, if he places a medkit in his inventory, the shortcut will be automatically added to his hotbar. + * This, in turn, dispatches a packet informing the server. + * The prior functionality will rarely be appreciated, however, as players rarely never have their medkit shortcut unbound. * @param player_guid the player * @param slot the hotbar slot number (one-indexed) * @param unk na; always zero? diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 6fd87305c..48d669c6b 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -334,7 +334,7 @@ class GamePacketTest extends Specification { shortcut.get.tile mustEqual "shortcut_macro" shortcut.get.effect1 mustEqual "NTU" shortcut.get.effect2 mustEqual "/platoon Incoming NTU spam!" - case default => + case _ => ko } } @@ -407,6 +407,27 @@ class GamePacketTest extends Specification { } } + "ChangeShortcutBankMessage" should { + val string = hex"29 4B00 20" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case ChangeShortcutBankMessage(player_guid, bank) => + player_guid mustEqual PlanetSideGUID(75) + bank mustEqual 2 + case default => + ko + } + } + + "encode" in { + val msg = ChangeShortcutBankMessage(PlanetSideGUID(75), 2) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + } + "DropItemMessage" should { val string = hex"37 4C00"