diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 44b7a782..9da9c70c 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -556,7 +556,7 @@ object GamePacketOpcode extends Enumeration { case 0xc6 => game.ZoneInfoMessage.decode case 0xc7 => noDecoder(LongRangeProjectileInfoMessage) // 0xc8 - case 0xc8 => noDecoder(WeaponLazeTargetPositionMessage) + case 0xc8 => game.WeaponLazeTargetPositionMessage.decode case 0xc9 => noDecoder(ModuleLimitsMessage) case 0xca => noDecoder(OutfitBenefitMessage) case 0xcb => noDecoder(EmpireChangeTimeMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/WeaponLazeTargetPositionMessage.scala b/common/src/main/scala/net/psforever/packet/game/WeaponLazeTargetPositionMessage.scala new file mode 100644 index 00000000..37430e50 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/WeaponLazeTargetPositionMessage.scala @@ -0,0 +1,39 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import net.psforever.types.Vector3 +import scodec.Codec +import scodec.codecs._ + +/** + * Dispatched to the server when a position is being marked by a laze pointer tool.
+ *
+ * When the laze tool is used, a progress bar window is displayed, along with the text "Acquiring Target Position." + * The player using the tool constantly sends packets to the server for as long as the progress bar is filling. + * In all, about fifty packets are sent. + * (Measured during low-load testing. + * The actual number of packets may be related to network load.)
+ *
+ * While firing, the player's movement is locked for the duration. + * The weapon fire can be aborted at any time, returning control. + * @param weapon_uid the laze pointer tool + * @param player_pos the position of (the player holding the) laze pointer + * @param lazed_pos position of the tip of the laze pointer's beam, or where it intersects something + */ +final case class WeaponLazeTargetPositionMessage(weapon_uid : PlanetSideGUID, + player_pos : Vector3, + lazed_pos : Vector3) + extends PlanetSideGamePacket { + type Packet = WeaponLazeTargetPositionMessage + def opcode = GamePacketOpcode.WeaponLazeTargetPositionMessage + def encode = WeaponLazeTargetPositionMessage.encode(this) +} + +object WeaponLazeTargetPositionMessage extends Marshallable[WeaponLazeTargetPositionMessage] { + implicit val codec : Codec[WeaponLazeTargetPositionMessage] = ( + ("weapon_uid" | PlanetSideGUID.codec) :: + ("player_pos" | Vector3.codec_pos) :: + ("lazed_pos" | Vector3.codec_pos) + ).as[WeaponLazeTargetPositionMessage] +} diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala index 5d695ffb..333704b4 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala @@ -271,6 +271,7 @@ object ObjectClass { final val bank = 132 final val nano_dispenser = 577 final val command_detonater = 213 + final val laze_pointer = 297 //unknown final val locker_container = 456 //strange item found in inventory slot #5, between holsters and grid @@ -547,7 +548,7 @@ object ObjectClass { case ObjectClass.bank => WeaponData.genericCodec case ObjectClass.nano_dispenser => WeaponData.genericCodec case ObjectClass.command_detonater => WeaponData.genericCodec - + case ObjectClass.laze_pointer => WeaponData.genericCodec diff --git a/common/src/test/scala/game/WeaponLazeTargetPositionMessageTest.scala b/common/src/test/scala/game/WeaponLazeTargetPositionMessageTest.scala new file mode 100644 index 00000000..c21ce137 --- /dev/null +++ b/common/src/test/scala/game/WeaponLazeTargetPositionMessageTest.scala @@ -0,0 +1,38 @@ +// Copyright (c) 2016 PSForever.net to present +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import net.psforever.types.Vector3 +import scodec.bits._ + +class WeaponLazeTargetPositionMessageTest extends Specification { + val string = hex"C8 4C00 6C2D7 65535 CA16 982D7 4A535 CA16" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case WeaponLazeTargetPositionMessage(weapon_uid, pos1, pos2) => + weapon_uid mustEqual PlanetSideGUID(76) + pos1.x mustEqual 3674.8438f + pos1.y mustEqual 2726.789f + pos1.z mustEqual 91.15625f + pos2.x mustEqual 3675.1875f + pos2.y mustEqual 2726.5781f + pos2.z mustEqual 91.15625f + case _ => + ko + } + } + + "encode" in { + val msg = WeaponLazeTargetPositionMessage( + PlanetSideGUID(76), + Vector3(3674.8438f, 2726.789f, 91.15625f), + Vector3(3675.1875f, 2726.5781f, 91.15625f) + ) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +} diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 64a3be52..5dc6479e 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -349,6 +349,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ WeaponFireMessage(seq_time, weapon_guid, projectile_guid, shot_origin, unk1, unk2, unk3, unk4, unk5, unk6, unk7) => log.info("WeaponFire: " + msg) + case msg @ WeaponLazeTargetPositionMessage(weapon, pos1, pos2) => + log.info("Lazing position: " + pos2.toString) + case msg @ HitMessage(seq_time, projectile_guid, unk1, hit_info, unk2, unk3, unk4) => log.info("Hit: " + msg)