From d2ae3dfab9a82893c5c7be5fd1be6496a2c40258 Mon Sep 17 00:00:00 2001 From: FateJH Date: Sat, 7 Oct 2017 21:57:20 -0400 Subject: [PATCH] initial TriggerSoundMessage packet work and tests --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/TriggerSoundMessage.scala | 77 +++++++++++++++++++ .../scala/game/TriggerSoundMessageTest.scala | 33 ++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/TriggerSoundMessage.scala create mode 100644 common/src/test/scala/game/TriggerSoundMessageTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 45d19e7a..f4ef9765 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -445,7 +445,7 @@ object GamePacketOpcode extends Enumeration { case 0x68 => noDecoder(DroppodFreefallingMessage) case 0x69 => game.AvatarFirstTimeEventMessage.decode case 0x6a => noDecoder(AggravatedDamageMessage) - case 0x6b => noDecoder(TriggerSoundMessage) + case 0x6b => game.TriggerSoundMessage.decode case 0x6c => noDecoder(LootItemMessage) case 0x6d => noDecoder(VehicleSubStateMessage) case 0x6e => noDecoder(SquadMembershipRequest) diff --git a/common/src/main/scala/net/psforever/packet/game/TriggerSoundMessage.scala b/common/src/main/scala/net/psforever/packet/game/TriggerSoundMessage.scala new file mode 100644 index 00000000..24cc5fa9 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/TriggerSoundMessage.scala @@ -0,0 +1,77 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import net.psforever.types.Vector3 +import scodec.Codec +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * An `Enumeration` of the sounds triggered by this packet. + * Twenty-one possible sounds are available for playback. + */ +object TriggeredSound extends Enumeration { + type Type = Value + + val + SpawnInTube, + Unknown1, + Hack, + HackDoor, + Unknown4, + LockedOut, + Unknown6, + Unknown7, + Unknown8, + Unknown9, + Unknown10, + Unknown11, + Unknown12, + Unknown13, + Unknown14, + Unknown15, + Unknown16, + Unknown17, + Unknown18, + Unknown19, + Unknown20 = Value + + implicit val codec = PacketHelpers.createEnumerationCodec(this, uintL(5)) +} + +/** + * Dispatched by the server to cause a sound to be played at a certain location in the world. + * @param sound the kind of sound + * @param pos the location where the sound gets played + * @param unk na; + * may be radius + * @param volume the volume of the sound at the origin (0.0f - 1.0f) + */ +final case class TriggerSoundMessage(sound : TriggeredSound.Value, + pos : Vector3, + unk : Int, + volume : Float) + extends PlanetSideGamePacket { + type Packet = TriggerSoundMessage + def opcode = GamePacketOpcode.TriggerSoundMessage + def encode = TriggerSoundMessage.encode(this) +} + +object TriggerSoundMessage extends Marshallable[TriggerSoundMessage] { + implicit val codec : Codec[TriggerSoundMessage] = ( + ("sound" | TriggeredSound.codec) :: + ("pos" | Vector3.codec_pos) :: + ("unk" | uintL(9)) :: + ("volume" | uint8L) + ).xmap[TriggerSoundMessage] ( + { + case a :: b :: c :: d :: HNil => + TriggerSoundMessage(a, b, c, d.toFloat * 0.0039215689f) + }, + { + case TriggerSoundMessage(a, b, c, d) => + a :: b :: c :: (d * 255f).toInt :: HNil + } + ) +} diff --git a/common/src/test/scala/game/TriggerSoundMessageTest.scala b/common/src/test/scala/game/TriggerSoundMessageTest.scala new file mode 100644 index 00000000..2db61b45 --- /dev/null +++ b/common/src/test/scala/game/TriggerSoundMessageTest.scala @@ -0,0 +1,33 @@ +// 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 TriggerSoundMessageTest extends Specification { + val string = hex"6B 1FD5E1B466DB3858F1FC" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case TriggerSoundMessage(sound, pos, unk2, volume) => + sound mustEqual TriggeredSound.HackDoor + pos.x mustEqual 1913.9531f + pos.y mustEqual 6042.8125f + pos.z mustEqual 45.609375f + unk2 mustEqual 30 + volume mustEqual 0.49803925f + case _ => + ko + } + } + + "encode" in { + val msg = TriggerSoundMessage(TriggeredSound.HackDoor, Vector3(1913.9531f, 6042.8125f, 45.609375f), 30, 0.49803925f) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +}