mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-04-29 16:25:30 +00:00
Packet: SplashHitMessage and tests (#106)
This commit is contained in:
parent
6001446cd5
commit
b6c1fcc29d
4 changed files with 152 additions and 1 deletions
|
|
@ -435,7 +435,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
// OPCODES 0x60-6f
|
// OPCODES 0x60-6f
|
||||||
case 0x60 => game.FavoritesMessage.decode
|
case 0x60 => game.FavoritesMessage.decode
|
||||||
case 0x61 => noDecoder(ObjectDetectedMessage)
|
case 0x61 => noDecoder(ObjectDetectedMessage)
|
||||||
case 0x62 => noDecoder(SplashHitMessage)
|
case 0x62 => game.SplashHitMessage.decode
|
||||||
case 0x63 => noDecoder(SetChatFilterMessage)
|
case 0x63 => noDecoder(SetChatFilterMessage)
|
||||||
case 0x64 => noDecoder(AvatarSearchCriteriaMessage)
|
case 0x64 => noDecoder(AvatarSearchCriteriaMessage)
|
||||||
case 0x65 => noDecoder(AvatarSearchResponse)
|
case 0x65 => noDecoder(AvatarSearchResponse)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
package net.psforever.packet.game
|
||||||
|
|
||||||
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
|
import net.psforever.types.Vector3
|
||||||
|
import scodec.Codec
|
||||||
|
import scodec.codecs._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entry of the target that was hit by splash damage.
|
||||||
|
* @param uid the target's uid
|
||||||
|
* @param pos the target's position (when hit)
|
||||||
|
* @param unk1 na
|
||||||
|
* @param unk2 na
|
||||||
|
*/
|
||||||
|
final case class SplashedTarget(uid : PlanetSideGUID,
|
||||||
|
pos : Vector3,
|
||||||
|
unk1 : Long,
|
||||||
|
unk2 : Option[Int])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatched to the server when a type of effect that influence multiple targets activates.<br>
|
||||||
|
* <br>
|
||||||
|
* Splash does not refer to the effect upon an applicable target.
|
||||||
|
* Splash denotes the fixed radius wherein a said effect exerts temporary influence.
|
||||||
|
* Being damaged is the most common splash effect; the jammering effect is another.
|
||||||
|
* A pain field does not count because it is an environmental constant.
|
||||||
|
* Lashing is considered different because it is a type of inheritable influence.<br>
|
||||||
|
* <br>
|
||||||
|
* Valid targets for splash are all interactive game objects that maintain a GUID.
|
||||||
|
* This includes: players, of course; vehicles, of course; doors; terminals; spawn tubes; and, such objects.
|
||||||
|
* Not all targets listed will actually be influenced by the effect carried by splash.<br>
|
||||||
|
* <br>
|
||||||
|
* The effect commonly modifies the visual depiction of the splash.
|
||||||
|
* Being able to "see" splash also does not necessarily mean that one will be influenced by it.
|
||||||
|
* Visually and spatially, it may seem to bleed through surfaces on occasion.
|
||||||
|
* The effect will not be carried, however.
|
||||||
|
* Splash will also respect the game's internal zoning and not pass through temporary obstacles like closed doors.
|
||||||
|
* Not being able to see splash also does not stop a target from being affected.
|
||||||
|
* The radius of influence is typically a bit larger than the visual indication.<br>
|
||||||
|
* <br>
|
||||||
|
* All sources of splash damage herein will be called "grenades" for simplicity.
|
||||||
|
* @param unk1 na
|
||||||
|
* @param projectile_uid the grenade's object
|
||||||
|
* @param projectile_pos the position where the grenade landed (where it is)
|
||||||
|
* @param unk2 na;
|
||||||
|
* frequently 42
|
||||||
|
* @param unk3 na;
|
||||||
|
* frequently 0
|
||||||
|
* @param projectile_vel the velocity of the grenade when it landed
|
||||||
|
* @param unk4 na
|
||||||
|
* @param targets a `List` of all targets influenced by the splash
|
||||||
|
*/
|
||||||
|
final case class SplashHitMessage(unk1 : Int,
|
||||||
|
projectile_uid : PlanetSideGUID,
|
||||||
|
projectile_pos : Vector3,
|
||||||
|
unk2 : Int,
|
||||||
|
unk3 : Int,
|
||||||
|
projectile_vel : Option[Vector3],
|
||||||
|
unk4 : Option[Int],
|
||||||
|
targets : List[SplashedTarget])
|
||||||
|
extends PlanetSideGamePacket {
|
||||||
|
type Packet = SplashHitMessage
|
||||||
|
def opcode = GamePacketOpcode.SplashHitMessage
|
||||||
|
def encode = SplashHitMessage.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object SplashedTarget extends Marshallable[SplashedTarget] {
|
||||||
|
implicit val codec : Codec[SplashedTarget] = (
|
||||||
|
("uid" | PlanetSideGUID.codec) ::
|
||||||
|
("pos" | Vector3.codec_pos) ::
|
||||||
|
("unk1" | uint32L) ::
|
||||||
|
optional(bool, "unk2" | uint16L)
|
||||||
|
).as[SplashedTarget]
|
||||||
|
}
|
||||||
|
|
||||||
|
object SplashHitMessage extends Marshallable[SplashHitMessage] {
|
||||||
|
implicit val codec : Codec[SplashHitMessage] = (
|
||||||
|
("unk1" | uintL(10)) ::
|
||||||
|
("projectile_uid" | PlanetSideGUID.codec) ::
|
||||||
|
("projectile_pos" | Vector3.codec_pos) ::
|
||||||
|
("unk2" | uint16L) ::
|
||||||
|
("unk3" | uintL(3)) ::
|
||||||
|
optional(bool, "projectile_vel" | Vector3.codec_vel) ::
|
||||||
|
optional(bool, "unk4" | uint16L) ::
|
||||||
|
("targets" | PacketHelpers.listOfNAligned(uint32L, 0, SplashedTarget.codec))
|
||||||
|
).as[SplashHitMessage]
|
||||||
|
}
|
||||||
60
common/src/test/scala/game/SplashHitMessageTest.scala
Normal file
60
common/src/test/scala/game/SplashHitMessageTest.scala
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
// 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 SplashHitMessageTest extends Specification {
|
||||||
|
val string = hex"62 7129e72b0c1dd1516ec58000051e01d8371f0100000025803616bb2a9ae50b000008889d00644bdd35454c45c000000400"
|
||||||
|
|
||||||
|
"decode" in {
|
||||||
|
PacketCoding.DecodePacket(string).require match {
|
||||||
|
case SplashHitMessage(unk1, projectile_uid, projectile_pos, unk2, unk3, projectile_vel, unk4, targets) =>
|
||||||
|
unk1 mustEqual 113
|
||||||
|
projectile_uid mustEqual PlanetSideGUID(40103)
|
||||||
|
projectile_pos.x mustEqual 3681.3438f
|
||||||
|
projectile_pos.y mustEqual 2728.9062f
|
||||||
|
projectile_pos.z mustEqual 90.921875f
|
||||||
|
unk2 mustEqual 0
|
||||||
|
unk3 mustEqual 0
|
||||||
|
projectile_vel.isDefined mustEqual true
|
||||||
|
projectile_vel.get.x mustEqual 2.21875f
|
||||||
|
projectile_vel.get.y mustEqual 0.90625f
|
||||||
|
projectile_vel.get.z mustEqual -1.125f
|
||||||
|
unk4.isDefined mustEqual false
|
||||||
|
targets.size mustEqual 2
|
||||||
|
//0
|
||||||
|
targets.head.uid mustEqual PlanetSideGUID(75)
|
||||||
|
targets.head.pos.x mustEqual 3674.8438f
|
||||||
|
targets.head.pos.y mustEqual 2726.789f
|
||||||
|
targets.head.pos.z mustEqual 91.15625f
|
||||||
|
targets.head.unk1 mustEqual 286326784L
|
||||||
|
targets.head.unk2.isDefined mustEqual false
|
||||||
|
//1
|
||||||
|
targets(1).uid mustEqual PlanetSideGUID(372)
|
||||||
|
targets(1).pos.x mustEqual 3679.1328f
|
||||||
|
targets(1).pos.y mustEqual 2722.6016f
|
||||||
|
targets(1).pos.z mustEqual 92.765625f
|
||||||
|
targets(1).unk1 mustEqual 268435456L
|
||||||
|
targets(1).unk2.isDefined mustEqual false
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode" in {
|
||||||
|
val msg = SplashHitMessage(113, PlanetSideGUID(40103),
|
||||||
|
Vector3(3681.3438f, 2728.9062f, 90.921875f), 0, 0,
|
||||||
|
Some(Vector3(2.21875f, 0.90625f, -1.125f)), None,
|
||||||
|
SplashedTarget(PlanetSideGUID(75), Vector3(3674.8438f, 2726.789f, 91.15625f), 286326784L, None) ::
|
||||||
|
SplashedTarget(PlanetSideGUID(372), Vector3(3679.1328f, 2722.6016f, 92.765625f), 268435456L, None) ::
|
||||||
|
Nil
|
||||||
|
)
|
||||||
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -351,6 +351,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case msg @ HitMessage(seq_time, projectile_guid, unk1, hit_info, unk2, unk3, unk4) =>
|
case msg @ HitMessage(seq_time, projectile_guid, unk1, hit_info, unk2, unk3, unk4) =>
|
||||||
log.info("Hit: " + msg)
|
log.info("Hit: " + msg)
|
||||||
|
|
||||||
|
case msg @ SplashHitMessage(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8) =>
|
||||||
|
log.info("SplashHitMessage: " + msg)
|
||||||
|
|
||||||
case msg @ AvatarFirstTimeEventMessage(avatar_guid, object_guid, unk1, event_name) =>
|
case msg @ AvatarFirstTimeEventMessage(avatar_guid, object_guid, unk1, event_name) =>
|
||||||
log.info("AvatarFirstTimeEvent: " + msg)
|
log.info("AvatarFirstTimeEvent: " + msg)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue