mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
commit
9a8e1e8f95
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.Angular
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
|
|
@ -16,18 +17,12 @@ import scodec.codecs._
|
|||
* The only concern is the direction the object is facing.
|
||||
* The angles are relative to the object's normal forward-facing and typically begin tracking at 0, 0 (forward-facing).
|
||||
* @param object_guid the object being manipulated (controlled)
|
||||
* @param pitch the angle with respect to the sky and the ground towards which the object is directed;
|
||||
* an 8-bit unsigned value;
|
||||
* 0 is perfectly level and forward-facing and mapped to 255;
|
||||
* positive rotation is downwards from forward-facing
|
||||
* @param yaw the angle with respect to the horizon towards which the object is directed;
|
||||
* an 8-bit unsigned value;
|
||||
* 0 is forward-facing, wrapping around at 127;
|
||||
* positive rotation is counter-clockwise of forward-facing
|
||||
* @param pitch the amount of pitch that affects orientation from forward facing (0)
|
||||
* @param yaw the amount of yaw that affects orientation from forward-facing (0)
|
||||
*/
|
||||
final case class ChildObjectStateMessage(object_guid : PlanetSideGUID,
|
||||
pitch : Int,
|
||||
yaw : Int)
|
||||
pitch : Float,
|
||||
yaw : Float)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = ChildObjectStateMessage
|
||||
def opcode = GamePacketOpcode.ChildObjectStateMessage
|
||||
|
|
@ -37,7 +32,7 @@ final case class ChildObjectStateMessage(object_guid : PlanetSideGUID,
|
|||
object ChildObjectStateMessage extends Marshallable[ChildObjectStateMessage] {
|
||||
implicit val codec : Codec[ChildObjectStateMessage] = (
|
||||
("object_guid" | PlanetSideGUID.codec) ::
|
||||
("pitch" | uint8L) ::
|
||||
("yaw" | uint8L)
|
||||
("pitch" | Angular.codec_pitch) ::
|
||||
("yaw" | Angular.codec_yaw(0f))
|
||||
).as[ChildObjectStateMessage]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
|
|
@ -23,25 +23,16 @@ import scodec.codecs._
|
|||
* @param parent_guid the container/connector object
|
||||
* @param child_guid the contained/connected object
|
||||
* @param pos where the contained/connected object will be placed after it has detached
|
||||
* @param roll the roll of the dropped item;
|
||||
* every `0x1` is 2.813 degrees;
|
||||
* every `0x10` is 45-degrees;
|
||||
* it wraps at `0x0` == `0x80` == top facing up
|
||||
* @param pitch the pitch of the dropped item;
|
||||
* every `0x1` is 2.813 degrees;
|
||||
* every `0x10` is 45-degrees;
|
||||
* it wraps at `0x0` == `0x80` == top facing up
|
||||
* @param yaw the yaw of the dropped item;
|
||||
* every `0x1` is 2.813 degrees counter clockwise from East;
|
||||
* every `0x10` is 45-degrees;
|
||||
* it wraps at `0x0` == `0x80` == front facing East
|
||||
* @param roll the amount of roll that affects orientation of the dropped item
|
||||
* @param pitch the amount of pitch that affects orientation of the dropped item
|
||||
* @param yaw the amount of yaw that affects orientation of the dropped item
|
||||
*/
|
||||
final case class ObjectDetachMessage(parent_guid : PlanetSideGUID,
|
||||
child_guid : PlanetSideGUID,
|
||||
pos : Vector3,
|
||||
roll : Int,
|
||||
pitch : Int,
|
||||
yaw : Int)
|
||||
roll : Float,
|
||||
pitch : Float,
|
||||
yaw : Float)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = ObjectDetachMessage
|
||||
def opcode = GamePacketOpcode.ObjectDetachMessage
|
||||
|
|
@ -53,8 +44,8 @@ object ObjectDetachMessage extends Marshallable[ObjectDetachMessage] {
|
|||
("parent_guid" | PlanetSideGUID.codec) ::
|
||||
("child_guid" | PlanetSideGUID.codec) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("roll" | uint8L) ::
|
||||
("pitch" | uint8L) ::
|
||||
("yaw" | uint8L)
|
||||
("roll" | Angular.codec_roll) ::
|
||||
("pitch" | Angular.codec_pitch) ::
|
||||
("yaw" | Angular.codec_yaw())
|
||||
).as[ObjectDetachMessage]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package net.psforever.packet.game
|
|||
|
||||
import net.psforever.newcodecs.newcodecs
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
|
@ -20,7 +20,7 @@ import shapeless.{::, HNil}
|
|||
* <br>
|
||||
* The avatar model normally moves from where it "currently" is to `pos`.
|
||||
* When `vel` is defined, `pos` is treated as where the avatar model starts its animation.
|
||||
* In that case, it sppears to teleport to `pos` to carry out the interpolated movement according to `vel`.
|
||||
* In that case, it appears to teleport to `pos` to carry out the interpolated movement according to `vel`.
|
||||
* After the move, it remains at essentially `pos + vel * t`.
|
||||
* The repositioning always takes the same amount of time.
|
||||
* The player model is left in a walking/running animation (in place) until directed otherwise.<br>
|
||||
|
|
@ -29,39 +29,15 @@ import shapeless.{::, HNil}
|
|||
* A demonstration of this is what happens when one player "runs past"/"into" another player running up stairs.
|
||||
* The climbing player is frequently reported by the other to appear to bounce over that player's head.
|
||||
* If the other player is off the ground, passing too near to the observer can cause a rubber band effect on trajectory.
|
||||
* This effect is entirely client-side to the observer and affects the moving player in no way.<br>
|
||||
* <br>
|
||||
* facingYaw:<br>
|
||||
* `0x00` -- E<br>
|
||||
* `0x10` -- NE<br>
|
||||
* `0x20` -- N<br>
|
||||
* `0x30` -- NW<br>
|
||||
* `0x40` -- W<br>
|
||||
* `0x50` -- SW<br>
|
||||
* `0x60` -- S<br>
|
||||
* `0x70` -- SE<br>
|
||||
* `0x80` -- E<br>
|
||||
* <br>
|
||||
* facingPitch:<br>
|
||||
* `0x00`-`0x20` -- downwards-facing angles, with `0x00` as forwards-facing<br>
|
||||
* `0x21`-`0x40` -- downwards-facing<br>
|
||||
* `0x41`-`0x59` -- upwards-facing<br>
|
||||
* `0x60`-`0x80` -- upwards-facing angles, with `0x80` as forwards-facing<br>
|
||||
* <br>
|
||||
* facingYawUpper:<br>
|
||||
* `0x00`-`0x20` -- turning to left, with `0x00` being forward-facing<br>
|
||||
* `0x21`-`0x40` -- facing leftwards<br>
|
||||
* `0x41`-`0x59` -- facing rightwards<br>
|
||||
* `0x60`-`0x80` -- turning to right, with `0x80` being forward-facing
|
||||
*
|
||||
* This effect is entirely client-side to the observer and affects the moving player in no way.
|
||||
* @param guid the avatar's guid
|
||||
* @param pos the position of the avatar in the world environment (in three coordinates)
|
||||
* @param vel an optional velocity
|
||||
* @param facingYaw the angle with respect to the horizon towards which the avatar is looking;
|
||||
* the model's whole body is facing this direction;
|
||||
* measurements are counter-clockwise from East
|
||||
* @param facingPitch the angle with respect to the sky and the ground towards which the avatar is looking
|
||||
* @param facingYawUpper the angle of the avatar's upper body with respect to its forward-facing direction
|
||||
* @param facingYaw a "yaw" angle
|
||||
* @param facingPitch a "pitch" angle
|
||||
* @param facingYawUpper a "yaw" angle that represents the angle of the avatar's upper body with respect to its forward-facing direction;
|
||||
* this number is normally 0 for forward facing;
|
||||
* the range is limited between approximately 61 degrees of center turned to left or right
|
||||
* @param unk1 na
|
||||
* @param is_crouching avatar is crouching
|
||||
* @param is_jumping avatar is jumping;
|
||||
|
|
@ -72,9 +48,9 @@ import shapeless.{::, HNil}
|
|||
final case class PlayerStateMessage(guid : PlanetSideGUID,
|
||||
pos : Vector3,
|
||||
vel : Option[Vector3],
|
||||
facingYaw : Int,
|
||||
facingPitch : Int,
|
||||
facingYawUpper : Int,
|
||||
facingYaw : Float,
|
||||
facingPitch : Float,
|
||||
facingYawUpper : Float,
|
||||
unk1 : Int,
|
||||
is_crouching : Boolean = false,
|
||||
is_jumping : Boolean = false,
|
||||
|
|
@ -117,9 +93,9 @@ object PlayerStateMessage extends Marshallable[PlayerStateMessage] {
|
|||
("guid" | PlanetSideGUID.codec) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
optional(bool, "vel" | Vector3.codec_vel) ::
|
||||
("facingYaw" | uint8L) ::
|
||||
("facingPitch" | uint8L) ::
|
||||
("facingYawUpper" | uint8L) ::
|
||||
("facingYaw" | Angular.codec_yaw()) ::
|
||||
("facingPitch" | Angular.codec_pitch) ::
|
||||
("facingYawUpper" | Angular.codec_yaw(0f)) ::
|
||||
("unk1" | uintL(10)) ::
|
||||
(bool >>:~ { fourBools =>
|
||||
newcodecs.binary_choice(!fourBools, booleanCodec, defaultCodec)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
|
|
@ -15,11 +15,11 @@ import scodec.codecs._
|
|||
* @param avatar_guid the player's GUID
|
||||
* @param pos where the player is in the world
|
||||
* @param vel how the player is moving
|
||||
* @param facingYaw the angle with respect to the horizon towards which the avatar is looking;
|
||||
* the model's whole body is facing this direction;
|
||||
* measurements are counter-clockwise from East
|
||||
* @param facingPitch the angle with respect to the sky and the ground towards which the avatar is looking
|
||||
* @param facingYawUpper the angle of the avatar's upper body with respect to its forward-facing direction
|
||||
* @param facingYaw a "yaw" angle
|
||||
* @param facingPitch a "pitch" angle
|
||||
* @param facingYawUpper a "yaw" angle that represents the angle of the avatar's upper body with respect to its forward-facing direction;
|
||||
* this number is normally 0 for forward facing;
|
||||
* the range is limited between approximately 61 degrees of center turned to left or right
|
||||
* @param seq_time na
|
||||
* @param unk1 na
|
||||
* @param is_crouching avatar is crouching
|
||||
|
|
@ -33,9 +33,9 @@ import scodec.codecs._
|
|||
final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID,
|
||||
pos : Vector3,
|
||||
vel : Option[Vector3],
|
||||
facingYaw : Int,
|
||||
facingPitch : Int,
|
||||
facingYawUpper : Int,
|
||||
facingYaw : Float,
|
||||
facingPitch : Float,
|
||||
facingYawUpper : Float,
|
||||
seq_time : Int,
|
||||
unk1 : Int,
|
||||
is_crouching : Boolean,
|
||||
|
|
@ -55,9 +55,9 @@ object PlayerStateMessageUpstream extends Marshallable[PlayerStateMessageUpstrea
|
|||
("avatar_guid" | PlanetSideGUID.codec) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("vel" | optional(bool, Vector3.codec_vel)) ::
|
||||
("facingYaw" | uint8L) ::
|
||||
("facingPitch" | uint8L) ::
|
||||
("facingYawUpper" | uint8L) ::
|
||||
("facingYaw" | Angular.codec_yaw()) ::
|
||||
("facingPitch" | Angular.codec_pitch) ::
|
||||
("facingYawUpper" | Angular.codec_yaw(0f)) ::
|
||||
("seq_time" | uintL(10)) ::
|
||||
("unk1" | uintL(3)) ::
|
||||
("is_crouching" | bool) ::
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import scodec.{Attempt, Codec, Err}
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
|
|
@ -16,23 +16,25 @@ import shapeless.{::, HNil}
|
|||
* This external force is not accumulative.
|
||||
* Also, the external force is only applied once the avatar is set to the provided position.<br>
|
||||
* <br>
|
||||
* `viewYawLim` defines a "range of angles" that the avatar may look centered on the supplied angle.
|
||||
* The avatar must be facing within 60-degrees of that direction, subjectively his left or his right.
|
||||
* The avatar's view is immediately set to the closest 60-degree mark if it is outside of that range.
|
||||
* The absolute angular displacement of the avatar is considered before applying this corrective behavior.
|
||||
* After rotating any number of times:
|
||||
* stopping in a valid part of the range is acceptable;
|
||||
* stopping in an invalid part of the range will cause the avatar to align to the __earliest__ still-valid 60-degree mark.
|
||||
* For that reason, even if the avatar's final angle is closest to the "left mark," it may re-align to the "right mark."
|
||||
* This also resets the avatar's angular displacement.
|
||||
* The angle defines the center of a range of angles that count as "in front of the avatar."
|
||||
* Specifically, this range is the upper body's turn limit.
|
||||
* A stationary player may look left and right, rotating their upper body only, until they hit a certain angle.
|
||||
* Normally, the player's whole body will then turn to accommodate turning further than this angle.
|
||||
* This packet marks that limit as a hard limit for rotation and will reset the player's model and camera if necessary.
|
||||
* While it is in effect, the player will not turn their whole body once they can no longer turn their upper body.
|
||||
* @param unk na
|
||||
* @param pos the position to move the character to in the world environment
|
||||
* @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect)
|
||||
* @param viewYawLim the center of the range of upper body angles, the player's actual yaw;
|
||||
* if this value is beyond its angular limit values,
|
||||
* the model will attempt to snap to what it considers the closest upper body turning limit angle;
|
||||
* the actual range is approximately `viewYawLimit +/- 61.8215`;
|
||||
* @param vel if defined, the velocity to apply to to the character at the given position
|
||||
* @see `PlayerStateMessageUpstream.facingYawUpper`
|
||||
* @see `PlayerStateMessage.facingYawUpper`
|
||||
*/
|
||||
final case class ShiftState(unk : Int,
|
||||
pos : Vector3,
|
||||
viewYawLim : Int,
|
||||
viewYawLim : Float,
|
||||
vel : Option[Vector3])
|
||||
|
||||
/**
|
||||
|
|
@ -55,7 +57,7 @@ final case class PlayerStateShiftMessage(state : Option[ShiftState],
|
|||
def encode = PlayerStateShiftMessage.encode(this)
|
||||
}
|
||||
|
||||
object ShiftState extends Marshallable[ShiftState] {
|
||||
object ShiftState {
|
||||
/**
|
||||
* An abbreviated constructor for creating `ShiftState`, assuming velocity is not applied.
|
||||
* @param unk na
|
||||
|
|
@ -64,7 +66,7 @@ object ShiftState extends Marshallable[ShiftState] {
|
|||
* @param vel the velocity to apply to to the character at the given position
|
||||
* @return a `ShiftState` object
|
||||
*/
|
||||
def apply(unk : Int, pos : Vector3, viewYawLim : Int, vel : Vector3) : ShiftState =
|
||||
def apply(unk : Int, pos : Vector3, viewYawLim : Float, vel : Vector3) : ShiftState =
|
||||
ShiftState(unk, pos, viewYawLim, Some(vel))
|
||||
|
||||
/**
|
||||
|
|
@ -74,24 +76,8 @@ object ShiftState extends Marshallable[ShiftState] {
|
|||
* @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect)
|
||||
* @return a `ShiftState` object
|
||||
*/
|
||||
def apply(unk : Int, pos : Vector3, viewYawLim : Int) : ShiftState =
|
||||
def apply(unk : Int, pos : Vector3, viewYawLim : Float) : ShiftState =
|
||||
ShiftState(unk, pos, viewYawLim, None)
|
||||
|
||||
implicit val codec : Codec[ShiftState] = (
|
||||
("unk1" | uintL(3)) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("viewYawLim" | uint8L) ::
|
||||
optional(bool, "pos" | Vector3.codec_vel)
|
||||
).xmap[ShiftState] (
|
||||
{
|
||||
case a :: b :: c :: d :: HNil =>
|
||||
ShiftState(a, b, c, d)
|
||||
},
|
||||
{
|
||||
case ShiftState(a, b, c, d) =>
|
||||
a :: b :: c :: d :: HNil
|
||||
}
|
||||
).as[ShiftState]
|
||||
}
|
||||
|
||||
object PlayerStateShiftMessage extends Marshallable[PlayerStateShiftMessage] {
|
||||
|
|
@ -120,8 +106,30 @@ object PlayerStateShiftMessage extends Marshallable[PlayerStateShiftMessage] {
|
|||
def apply(unk : Int) : PlayerStateShiftMessage =
|
||||
PlayerStateShiftMessage(None, Some(unk))
|
||||
|
||||
private val shift_codec : Codec[ShiftState] = (
|
||||
/*
|
||||
IMPORTANT:
|
||||
Packet data indicates that viewYawLimit is an 8u value.
|
||||
When read as an 8u value, the resulting number does not map to directions properly.
|
||||
As a 7u value, the numbers maps better so the first bit will be ignored.
|
||||
*/
|
||||
("unk" | uintL(3)) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("viewYawLim" | Angular.codec_yaw()) ::
|
||||
optional(bool, "pos" | Vector3.codec_vel)
|
||||
).xmap[ShiftState] (
|
||||
{
|
||||
case a :: b :: c :: d :: HNil =>
|
||||
ShiftState(a, b, c, d)
|
||||
},
|
||||
{
|
||||
case ShiftState(a, b, c, d) =>
|
||||
a :: b :: c :: d :: HNil
|
||||
}
|
||||
).as[ShiftState]
|
||||
|
||||
implicit val codec : Codec[PlayerStateShiftMessage] = (
|
||||
optional(bool, "state" | ShiftState.codec) ::
|
||||
optional(bool, "state" | shift_codec) ::
|
||||
optional(bool, "unk" | uintL(3))
|
||||
).xmap[PlayerStateShiftMessage] (
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.newcodecs.newcodecs
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
//TODO write more thorough comments later.
|
||||
/**
|
||||
|
|
@ -14,15 +12,7 @@ import shapeless.{::, HNil}
|
|||
* @param vehicle_guid the vehicle
|
||||
* @param unk1 na
|
||||
* @param pos the xyz-coordinate location in the world
|
||||
* @param roll the amount of roll that affects orientation;
|
||||
* 0.0f is flat to the ground;
|
||||
* roll-right rotation increases angle
|
||||
* @param pitch the amount of pitch that affects orientation;
|
||||
* 0.0f is flat to the ground;
|
||||
* front-up rotation increases angle
|
||||
* @param yaw the amount of yaw that affects orientation;
|
||||
* 0.0f is North (before the correction, 0.0f is East);
|
||||
* clockwise rotation increases angle
|
||||
* @param ang the orientation of the vehicle
|
||||
* @param vel optional movement data
|
||||
* @param unk2 na
|
||||
* @param unk3 na
|
||||
|
|
@ -38,9 +28,7 @@ import shapeless.{::, HNil}
|
|||
final case class VehicleStateMessage(vehicle_guid : PlanetSideGUID,
|
||||
unk1 : Int,
|
||||
pos : Vector3,
|
||||
roll : Float,
|
||||
pitch : Float,
|
||||
yaw : Float,
|
||||
ang : Vector3,
|
||||
vel : Option[Vector3],
|
||||
unk2 : Option[Int],
|
||||
unk3 : Int,
|
||||
|
|
@ -55,13 +43,23 @@ final case class VehicleStateMessage(vehicle_guid : PlanetSideGUID,
|
|||
}
|
||||
|
||||
object VehicleStateMessage extends Marshallable[VehicleStateMessage] {
|
||||
/**
|
||||
* Calculate common orientation from little-endian bit data.
|
||||
* @see `Angular.codec_roll`
|
||||
* @see `Angular.codec_pitch`
|
||||
* @see `Angular.codec_yaw`
|
||||
*/
|
||||
private val codec_orient : Codec[Vector3] = (
|
||||
("roll" | Angular.codec_roll(10)) ::
|
||||
("pitch" | Angular.codec_pitch(10)) ::
|
||||
("yaw" | Angular.codec_yaw(10, 90f))
|
||||
).as[Vector3]
|
||||
|
||||
implicit val codec : Codec[VehicleStateMessage] = (
|
||||
("vehicle_guid" | PlanetSideGUID.codec) ::
|
||||
("unk1" | uintL(3)) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("roll" | newcodecs.q_float(0.0f, 360.0f, 10)) ::
|
||||
("pitch" | newcodecs.q_float(360.0f, 0.0f, 10)) ::
|
||||
("yaw" | newcodecs.q_float(360.0f, 0.0f, 10)) ::
|
||||
("ang" | codec_orient) ::
|
||||
optional(bool, "vel" | Vector3.codec_vel) ::
|
||||
optional(bool, "unk2" | uintL(5)) ::
|
||||
("unk3" | uintL(7)) ::
|
||||
|
|
@ -69,27 +67,5 @@ object VehicleStateMessage extends Marshallable[VehicleStateMessage] {
|
|||
("wheel_direction" | uintL(5)) ::
|
||||
("int5" | bool) ::
|
||||
("int6" | bool)
|
||||
).xmap[VehicleStateMessage] (
|
||||
{
|
||||
case guid :: u1 :: pos :: roll :: pitch :: yaw :: vel :: u2 :: u3 :: u4 :: wheel :: u5 :: u6 :: HNil =>
|
||||
var northCorrectedYaw : Float = yaw + 90f
|
||||
if(northCorrectedYaw > 360f) {
|
||||
northCorrectedYaw = northCorrectedYaw - 360f
|
||||
}
|
||||
VehicleStateMessage(guid, u1, pos, roll, pitch, northCorrectedYaw, vel, u2, u3, u4, wheel, u5, u6)
|
||||
},
|
||||
|
||||
{
|
||||
case VehicleStateMessage(guid, u1, pos, roll, pitch, yaw, vel, u2, u3, u4, wheel, u5, u6) =>
|
||||
var northCorrectedYaw : Float = yaw - 90f
|
||||
//TODO this invites imprecision
|
||||
while(northCorrectedYaw < 0f) {
|
||||
northCorrectedYaw = 360f + northCorrectedYaw
|
||||
}
|
||||
if(northCorrectedYaw > 360f) {
|
||||
northCorrectedYaw = northCorrectedYaw % 360f
|
||||
}
|
||||
guid :: u1 :: pos :: roll :: pitch :: northCorrectedYaw :: vel :: u2 :: u3 :: u4 :: wheel :: u5 :: u6 :: HNil
|
||||
}
|
||||
)
|
||||
).as[VehicleStateMessage]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.packet.game.objectcreate
|
||||
|
||||
import net.psforever.packet.{Marshallable, PacketHelpers}
|
||||
import net.psforever.types.{CharacterGender, ExoSuitType, GrenadeState, PlanetSideEmpire}
|
||||
import net.psforever.types._
|
||||
import scodec.{Attempt, Codec, Err}
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
|
@ -74,8 +74,10 @@ final case class BasicCharacterData(name : String,
|
|||
* if the option is selected, allies with see either "[`outfit_name`]" or "{No Outfit}" under the player's name
|
||||
* @param outfit_logo the decal seen on the player's exo-suit (and beret and cap) associated with the player's outfit;
|
||||
* if there is a variable color for that decal, the faction-appropriate one is selected
|
||||
* @param facingPitch the angle with respect to the sky and the ground towards which the avatar is looking
|
||||
* @param facingYawUpper the angle of the avatar's upper body with respect to its forward-facing direction
|
||||
* @param facingPitch a "pitch" angle
|
||||
* @param facingYawUpper a "yaw" angle that represents the angle of the avatar's upper body with respect to its forward-facing direction;
|
||||
* this number is normally 0 for forward facing;
|
||||
* the range is limited between approximately 61 degrees of center turned to left or right
|
||||
* @param lfs this player is looking for a squad;
|
||||
* all allies will see the phrase "[Looking for Squad]" under the player's name
|
||||
* @param is_cloaking avatar is cloaked by virtue of an Infiltration Suit
|
||||
|
|
@ -101,8 +103,8 @@ final case class CharacterAppearanceData(pos : PlacementData,
|
|||
outfit_name : String,
|
||||
outfit_logo : Int,
|
||||
backpack : Boolean,
|
||||
facingPitch : Int,
|
||||
facingYawUpper : Int,
|
||||
facingPitch : Float,
|
||||
facingYawUpper : Float,
|
||||
lfs : Boolean,
|
||||
grenade_state : GrenadeState.Value,
|
||||
is_cloaking : Boolean,
|
||||
|
|
@ -168,8 +170,8 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
|
|||
ignore(1) :: //unknown
|
||||
("backpack" | bool) :: //requires alt_model flag (does NOT require health == 0)
|
||||
bool :: //stream misalignment when set
|
||||
("facingPitch" | uint8L) ::
|
||||
("facingYawUpper" | uint8L) ::
|
||||
("facingPitch" | Angular.codec_pitch) ::
|
||||
("facingYawUpper" | Angular.codec_yaw(0f)) ::
|
||||
ignore(1) :: //unknown
|
||||
conditional(alt_model, bool) :: //alt_model flag adds a bit before lfs
|
||||
ignore(1) :: //an alternate lfs?
|
||||
|
|
|
|||
|
|
@ -2,22 +2,19 @@
|
|||
package net.psforever.packet.game.objectcreate
|
||||
|
||||
import net.psforever.packet.Marshallable
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{Angular, Vector3}
|
||||
import scodec.codecs._
|
||||
import scodec.Codec
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
/**
|
||||
* A specific location and heading in game world coordinates and game world measurements.
|
||||
* @param coord the xyz-coordinate location in the world
|
||||
* @param roll the amount of roll that affects orientation
|
||||
* @param pitch the amount of pitch that affects orientation
|
||||
* @param yaw the amount of yaw that affects orientation
|
||||
* @param orient the ijk-orientation around the object's center
|
||||
* @param vel optional movement data (that occurs upon placement)
|
||||
*/
|
||||
final case class PlacementData(coord : Vector3,
|
||||
roll : Int,
|
||||
pitch : Int,
|
||||
yaw : Int,
|
||||
orient : Vector3,
|
||||
vel : Option[Vector3] = None
|
||||
) extends StreamBitSize {
|
||||
override def bitsize : Long = {
|
||||
|
|
@ -35,7 +32,7 @@ object PlacementData extends Marshallable[PlacementData] {
|
|||
* @return a `PlacementData` object
|
||||
*/
|
||||
def apply(x : Float, y : Float, z : Float) : PlacementData =
|
||||
new PlacementData(Vector3(x, y, z), 0, 0, 0)
|
||||
new PlacementData(Vector3(x, y, z), Vector3(0f,0f,0f))
|
||||
|
||||
/**
|
||||
* An abbreviated constructor for creating `PlacementData`, ignoring the `Vector3` for position data, supplying other important fields.
|
||||
|
|
@ -47,8 +44,8 @@ object PlacementData extends Marshallable[PlacementData] {
|
|||
* @param yaw the amount of yaw that affects orientation
|
||||
* @return a `PlacementData` object
|
||||
*/
|
||||
def apply(x : Float, y : Float, z : Float, roll : Int, pitch : Int, yaw : Int) : PlacementData =
|
||||
new PlacementData(Vector3(x, y, z), roll, pitch, yaw)
|
||||
def apply(x : Float, y : Float, z : Float, roll : Float, pitch : Float, yaw : Float) : PlacementData =
|
||||
new PlacementData(Vector3(x, y, z), Vector3(roll, pitch, yaw))
|
||||
|
||||
/**
|
||||
* An abbreviated constructor for creating `PlacementData`, ignoring the `Vector3` for position data, supplying all other fields.
|
||||
|
|
@ -61,14 +58,23 @@ object PlacementData extends Marshallable[PlacementData] {
|
|||
* @param vel optional movement data that occurs upon placement
|
||||
* @return a `PlacementData` object
|
||||
*/
|
||||
def apply(x : Float, y : Float, z : Float, roll : Int, pitch : Int, yaw : Int, vel : Vector3) : PlacementData =
|
||||
new PlacementData(Vector3(x, y, z), roll, pitch, yaw, Some(vel))
|
||||
def apply(x : Float, y : Float, z : Float, roll : Float, pitch : Float, yaw : Float, vel : Vector3) : PlacementData =
|
||||
new PlacementData(Vector3(x, y, z), Vector3(roll, pitch, yaw), Some(vel))
|
||||
|
||||
implicit val codec : Codec[PlacementData] = (
|
||||
("coord" | Vector3.codec_pos) ::
|
||||
("roll" | uint8L) ::
|
||||
("pitch" | uint8L) ::
|
||||
("yaw" | uint8L) ::
|
||||
("roll" | Angular.codec_roll) ::
|
||||
("pitch" | Angular.codec_pitch) ::
|
||||
("yaw" | Angular.codec_yaw()) ::
|
||||
optional(bool, "vel" | Vector3.codec_vel)
|
||||
).as[PlacementData]
|
||||
).xmap[PlacementData] (
|
||||
{
|
||||
case xyz :: i :: j :: k :: vel :: HNil =>
|
||||
PlacementData(xyz, Vector3(i, j, k), vel)
|
||||
},
|
||||
{
|
||||
case PlacementData(xyz, Vector3(i, j, k), vel) =>
|
||||
xyz :: i :: j :: k :: vel :: HNil
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
103
common/src/main/scala/net/psforever/types/Angular.scala
Normal file
103
common/src/main/scala/net/psforever/types/Angular.scala
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.types
|
||||
|
||||
import net.psforever.newcodecs.newcodecs
|
||||
import scodec.Codec
|
||||
import scodec.codecs.ignore
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
/**
|
||||
* A series of `Codec`s designed to work with convert between 8-bit angle values in the packets and `Float` numbers.
|
||||
* As far as the data is concerned, the first bit appears to be ignored when it comes to the actual angle measurement.
|
||||
* The latter seven bits map between 0 to 360 perfectly (according to the game).
|
||||
*/
|
||||
object Angular {
|
||||
//roll
|
||||
val codec_roll : Codec[Float] = (
|
||||
ignore(1) ::
|
||||
codec_roll(7)
|
||||
).xmap[Float] (
|
||||
{
|
||||
case _ :: roll :: HNil =>
|
||||
roll
|
||||
},
|
||||
{
|
||||
case roll : Float =>
|
||||
() :: roll :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
def codec_roll(bits : Int) : Codec[Float] = newcodecs.q_float(0.0f, 360.0f, bits)
|
||||
|
||||
//pitch
|
||||
val codec_pitch : Codec[Float] = (
|
||||
ignore(1) ::
|
||||
codec_pitch(7)
|
||||
).xmap[Float] (
|
||||
{
|
||||
case _ :: pitch :: HNil =>
|
||||
pitch
|
||||
},
|
||||
{
|
||||
case pitch : Float =>
|
||||
() :: pitch :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
def codec_pitch(bits : Int) : Codec[Float] = newcodecs.q_float(360.0f, 0.0f, bits).xmap[Float] (
|
||||
{
|
||||
case pitch =>
|
||||
decodeCorrectedAngle(pitch)
|
||||
},
|
||||
{
|
||||
case pitch : Float =>
|
||||
encodeCorrectedAngle(pitch)
|
||||
}
|
||||
)
|
||||
|
||||
//yaw
|
||||
def codec_yaw(North : Float = 90.0f) : Codec[Float] = (
|
||||
ignore(1) ::
|
||||
codec_yaw(7, North)
|
||||
).xmap[Float] (
|
||||
{
|
||||
case _ :: yaw :: HNil =>
|
||||
yaw
|
||||
},
|
||||
{
|
||||
case yaw : Float =>
|
||||
() :: yaw :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
def codec_yaw(bits : Int, North : Float) : Codec[Float] = newcodecs.q_float(360.0f, 0.0f, bits).xmap[Float] (
|
||||
{
|
||||
case yaw =>
|
||||
decodeCorrectedAngle(yaw, North)
|
||||
},
|
||||
{
|
||||
case yaw : Float =>
|
||||
encodeCorrectedAngle(yaw, North)
|
||||
}
|
||||
)
|
||||
|
||||
//support
|
||||
def decodeCorrectedAngle(angle : Float, correction : Float = 0f) : Float = {
|
||||
var correctedAng : Float = angle + correction
|
||||
if(correctedAng >= 360f) {
|
||||
correctedAng = correctedAng - 360f
|
||||
}
|
||||
correctedAng
|
||||
}
|
||||
|
||||
def encodeCorrectedAngle(angle : Float, correction : Float = 0f) : Float = {
|
||||
var correctedAng : Float = angle - correction
|
||||
if(correctedAng <= 0f) {
|
||||
correctedAng = 360f + correctedAng % 360f
|
||||
}
|
||||
else if(correctedAng > 360f) {
|
||||
correctedAng = correctedAng % 360f
|
||||
}
|
||||
correctedAng
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ package net.psforever.types
|
|||
import net.psforever.newcodecs._
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
final case class Vector3(x : Float,
|
||||
y : Float,
|
||||
|
|
|
|||
|
|
@ -34,23 +34,190 @@ class CodecTest extends Specification {
|
|||
}
|
||||
|
||||
"Vector3" should {
|
||||
val string_pos = hex"6E2D762222B616"
|
||||
val string_vel = hex"857D4E0FFFC0"
|
||||
"position" should {
|
||||
val string_pos = hex"6E2D762222B616"
|
||||
|
||||
"decode position" in {
|
||||
Vector3.codec_pos.decode(string_pos.bits).require.value mustEqual Vector3(3674.859375f, 1092.7656f, 90.84375f)
|
||||
"decode" in {
|
||||
Vector3.codec_pos.decode(string_pos.bits).require.value mustEqual Vector3(3674.859375f, 1092.7656f, 90.84375f)
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
Vector3.codec_pos.encode(Vector3(3674.859375f, 1092.7656f, 90.84375f)).require.bytes mustEqual string_pos
|
||||
}
|
||||
}
|
||||
|
||||
"encode position" in {
|
||||
Vector3.codec_pos.encode(Vector3(3674.859375f, 1092.7656f, 90.84375f)).require.bytes mustEqual string_pos
|
||||
"velocity" should {
|
||||
val string_vel = hex"857D4E0FFFC0"
|
||||
|
||||
"decode" in {
|
||||
Vector3.codec_vel.decode(string_vel.bits).require.value mustEqual Vector3(-3.84375f, 2.59375f, 255.96875f)
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
Vector3.codec_vel.encode(Vector3(-3.84375f, 2.59375f, 255.96875f)).require.bytes mustEqual string_vel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Angular" should {
|
||||
"roll" should {
|
||||
val string_roll_0 = hex"00"
|
||||
val string_roll_90 = hex"20"
|
||||
val string_roll_180 = hex"40"
|
||||
val string_roll_270 = hex"60"
|
||||
|
||||
"decode (0)" in {
|
||||
Angular.codec_roll.decode(string_roll_0.bits).require.value mustEqual 0f
|
||||
}
|
||||
|
||||
"decode (90)" in {
|
||||
Angular.codec_roll.decode(string_roll_90.bits).require.value mustEqual 90f
|
||||
}
|
||||
|
||||
"decode (180)" in {
|
||||
Angular.codec_roll.decode(string_roll_180.bits).require.value mustEqual 180f
|
||||
}
|
||||
|
||||
"decode (270)" in {
|
||||
Angular.codec_roll.decode(string_roll_270.bits).require.value mustEqual 270f
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
Angular.codec_roll.encode(0f).require.bytes mustEqual string_roll_0
|
||||
}
|
||||
|
||||
"encode (90)" in {
|
||||
Angular.codec_roll.encode(90f).require.bytes mustEqual string_roll_90
|
||||
}
|
||||
|
||||
"encode (180)" in {
|
||||
Angular.codec_roll.encode(180f).require.bytes mustEqual string_roll_180
|
||||
}
|
||||
|
||||
"encode (270)" in {
|
||||
Angular.codec_roll.encode(270f).require.bytes mustEqual string_roll_270
|
||||
}
|
||||
}
|
||||
|
||||
"decode velocity" in {
|
||||
Vector3.codec_vel.decode(string_vel.bits).require.value mustEqual Vector3(-3.84375f, 2.59375f, 255.96875f)
|
||||
"pitch" should {
|
||||
val string_pitch_0 = hex"00"
|
||||
val string_pitch_90 = hex"60"
|
||||
val string_pitch_180 = hex"40"
|
||||
val string_pitch_270 = hex"20"
|
||||
|
||||
"decode (0)" in {
|
||||
Angular.codec_pitch.decode(string_pitch_0.bits).require.value mustEqual 0f
|
||||
}
|
||||
|
||||
"decode (90)" in {
|
||||
Angular.codec_pitch.decode(string_pitch_90.bits).require.value mustEqual 90f
|
||||
}
|
||||
|
||||
"decode (180)" in {
|
||||
Angular.codec_pitch.decode(string_pitch_180.bits).require.value mustEqual 180f
|
||||
}
|
||||
|
||||
"decode (270)" in {
|
||||
Angular.codec_pitch.decode(string_pitch_270.bits).require.value mustEqual 270f
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
Angular.codec_pitch.encode(0f).require.bytes mustEqual string_pitch_0
|
||||
}
|
||||
|
||||
"encode (90)" in {
|
||||
Angular.codec_pitch.encode(90f).require.bytes mustEqual string_pitch_90
|
||||
}
|
||||
|
||||
"encode (180)" in {
|
||||
Angular.codec_pitch.encode(180f).require.bytes mustEqual string_pitch_180
|
||||
}
|
||||
|
||||
"encode (270)" in {
|
||||
Angular.codec_pitch.encode(270f).require.bytes mustEqual string_pitch_270
|
||||
}
|
||||
}
|
||||
|
||||
"encode velocity" in {
|
||||
Vector3.codec_vel.encode(Vector3(-3.84375f, 2.59375f, 255.96875f)).require.bytes mustEqual string_vel
|
||||
"yaw, normal" should {
|
||||
val string_pitch_0 = hex"00"
|
||||
val string_pitch_90 = hex"60"
|
||||
val string_pitch_180 = hex"40"
|
||||
val string_pitch_270 = hex"20"
|
||||
val string_yaw_0 = hex"20"
|
||||
val string_yaw_90 = hex"00"
|
||||
val string_yaw_180 = hex"60"
|
||||
val string_yaw_270 = hex"40"
|
||||
|
||||
"decode (0)" in {
|
||||
Angular.codec_yaw(0f).decode(string_yaw_0.bits).require.value mustEqual 270f
|
||||
}
|
||||
|
||||
"decode (90)" in {
|
||||
Angular.codec_yaw(0f).decode(string_yaw_90.bits).require.value mustEqual 0f
|
||||
}
|
||||
|
||||
"decode (180)" in {
|
||||
Angular.codec_yaw(0f).decode(string_yaw_180.bits).require.value mustEqual 90f
|
||||
}
|
||||
|
||||
"decode (270)" in {
|
||||
Angular.codec_yaw(0f).decode(string_yaw_270.bits).require.value mustEqual 180f
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
Angular.codec_yaw(0f).encode(0f).require.bytes mustEqual string_pitch_0
|
||||
}
|
||||
|
||||
"encode (90)" in {
|
||||
Angular.codec_yaw(0f).encode(90f).require.bytes mustEqual string_pitch_90
|
||||
}
|
||||
|
||||
"encode (180)" in {
|
||||
Angular.codec_yaw(0f).encode(180f).require.bytes mustEqual string_pitch_180
|
||||
}
|
||||
|
||||
"encode (270)" in {
|
||||
Angular.codec_yaw(0f).encode(270f).require.bytes mustEqual string_pitch_270
|
||||
}
|
||||
}
|
||||
|
||||
"yaw, North-corrected" should {
|
||||
val string_yaw_0 = hex"20"
|
||||
val string_yaw_90 = hex"00"
|
||||
val string_yaw_180 = hex"60"
|
||||
val string_yaw_270 = hex"40"
|
||||
|
||||
"decode (0)" in {
|
||||
Angular.codec_yaw().decode(string_yaw_0.bits).require.value mustEqual 0f
|
||||
}
|
||||
|
||||
"decode (90)" in {
|
||||
Angular.codec_yaw().decode(string_yaw_90.bits).require.value mustEqual 90f
|
||||
}
|
||||
|
||||
"decode (180)" in {
|
||||
Angular.codec_yaw().decode(string_yaw_180.bits).require.value mustEqual 180f
|
||||
}
|
||||
|
||||
"decode (270)" in {
|
||||
Angular.codec_yaw().decode(string_yaw_270.bits).require.value mustEqual 270f
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
Angular.codec_yaw().encode(0f).require.bytes mustEqual string_yaw_0
|
||||
}
|
||||
|
||||
"encode (90)" in {
|
||||
Angular.codec_yaw().encode(90f).require.bytes mustEqual string_yaw_90
|
||||
}
|
||||
|
||||
"encode (180)" in {
|
||||
Angular.codec_yaw().encode(180f).require.bytes mustEqual string_yaw_180
|
||||
}
|
||||
|
||||
"encode (270)" in {
|
||||
Angular.codec_yaw().encode(270f).require.bytes mustEqual string_yaw_270
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@ class ChildObjectStateMessageTest extends Specification {
|
|||
PacketCoding.DecodePacket(string).require match {
|
||||
case ChildObjectStateMessage(object_guid, pitch, yaw) =>
|
||||
object_guid mustEqual PlanetSideGUID(2916)
|
||||
pitch mustEqual 6
|
||||
yaw mustEqual 71
|
||||
pitch mustEqual 343.125f
|
||||
yaw mustEqual 160.3125f
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = ChildObjectStateMessage(PlanetSideGUID(2916), 6, 71)
|
||||
val msg = ChildObjectStateMessage(PlanetSideGUID(2916), 343.125f, 160.3125f)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
|
|
|
|||
|
|
@ -180,9 +180,9 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
char.appearance.pos.coord.x mustEqual 3674.8438f
|
||||
char.appearance.pos.coord.y mustEqual 2726.789f
|
||||
char.appearance.pos.coord.z mustEqual 91.15625f
|
||||
char.appearance.pos.roll mustEqual 0
|
||||
char.appearance.pos.pitch mustEqual 0
|
||||
char.appearance.pos.yaw mustEqual 19
|
||||
char.appearance.pos.orient.x mustEqual 0
|
||||
char.appearance.pos.orient.y mustEqual 0f
|
||||
char.appearance.pos.orient.z mustEqual 36.5625f
|
||||
char.appearance.basic_appearance.name mustEqual "IlllIIIlllIlIllIlllIllI"
|
||||
char.appearance.basic_appearance.faction mustEqual PlanetSideEmpire.VS
|
||||
char.appearance.basic_appearance.sex mustEqual CharacterGender.Female
|
||||
|
|
@ -195,8 +195,8 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
char.appearance.outfit_name mustEqual ""
|
||||
char.appearance.outfit_logo mustEqual 0
|
||||
char.appearance.backpack mustEqual false
|
||||
char.appearance.facingPitch mustEqual 127
|
||||
char.appearance.facingYawUpper mustEqual 181
|
||||
char.appearance.facingPitch mustEqual 2.8125f
|
||||
char.appearance.facingYawUpper mustEqual 210.9375f
|
||||
char.appearance.lfs mustEqual true
|
||||
char.appearance.grenade_state mustEqual GrenadeState.None
|
||||
char.appearance.is_cloaking mustEqual false
|
||||
|
|
@ -367,8 +367,7 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
val app = CharacterAppearanceData(
|
||||
PlacementData(
|
||||
Vector3(3674.8438f, 2726.789f, 91.15625f),
|
||||
0, 0,
|
||||
19
|
||||
Vector3(0f, 0f, 36.5625f)
|
||||
),
|
||||
BasicCharacterData(
|
||||
"IlllIIIlllIlIllIlllIllI",
|
||||
|
|
@ -384,7 +383,7 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
"",
|
||||
0,
|
||||
false,
|
||||
127, 181,
|
||||
2.8125f, 210.9375f,
|
||||
true,
|
||||
GrenadeState.None,
|
||||
false,
|
||||
|
|
@ -422,7 +421,8 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
val ori_bitv = string_testchar.toBitVector
|
||||
pkt_bitv.take(153) mustEqual ori_bitv.take(153) //skip 1
|
||||
pkt_bitv.drop(154).take(422) mustEqual ori_bitv.drop(154).take(422) //skip 126
|
||||
pkt_bitv.drop(702) mustEqual ori_bitv.drop(702)
|
||||
pkt_bitv.drop(702).take(29) mustEqual ori_bitv.drop(702).take(29) //skip 1
|
||||
pkt_bitv.drop(732) mustEqual ori_bitv.drop(732)
|
||||
//TODO work on DetailedCharacterData to make this pass as a single stream
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
projectile.pos.coord.x mustEqual 4644.5938f
|
||||
projectile.pos.coord.y mustEqual 5472.0938f
|
||||
projectile.pos.coord.z mustEqual 82.375f
|
||||
projectile.pos.roll mustEqual 0
|
||||
projectile.pos.pitch mustEqual 245
|
||||
projectile.pos.yaw mustEqual 227
|
||||
projectile.pos.orient.x mustEqual 0f
|
||||
projectile.pos.orient.y mustEqual 30.9375f
|
||||
projectile.pos.orient.z mustEqual 171.5625f
|
||||
projectile.unk1 mustEqual 0
|
||||
projectile.unk2 mustEqual TrackedProjectileData.striker_missile_targetting_projectile_data
|
||||
case _ =>
|
||||
|
|
@ -88,9 +88,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4579.3438f
|
||||
drop.pos.coord.y mustEqual 5615.0703f
|
||||
drop.pos.coord.z mustEqual 72.953125f
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.yaw mustEqual 125
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 98.4375f
|
||||
drop.obj.isInstanceOf[CommonTerminalData] mustEqual true
|
||||
val term = drop.obj.asInstanceOf[CommonTerminalData]
|
||||
term.faction mustEqual PlanetSideEmpire.NC
|
||||
|
|
@ -249,9 +249,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
flag.pos.coord.x mustEqual 3912.0312f
|
||||
flag.pos.coord.y mustEqual 5169.4375f
|
||||
flag.pos.coord.z mustEqual 59.96875f
|
||||
flag.pos.roll mustEqual 0
|
||||
flag.pos.pitch mustEqual 0
|
||||
flag.pos.yaw mustEqual 15
|
||||
flag.pos.orient.x mustEqual 0f
|
||||
flag.pos.orient.y mustEqual 0f
|
||||
flag.pos.orient.z mustEqual 47.8125f
|
||||
flag.faction mustEqual PlanetSideEmpire.NC
|
||||
flag.unk1 mustEqual 21
|
||||
flag.unk2 mustEqual 4
|
||||
|
|
@ -274,9 +274,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4708.461f
|
||||
drop.pos.coord.y mustEqual 5547.539f
|
||||
drop.pos.coord.z mustEqual 72.703125f
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.yaw mustEqual 91
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 194.0625f
|
||||
drop.obj.isInstanceOf[ACEData] mustEqual true
|
||||
val ace = drop.obj.asInstanceOf[ACEData]
|
||||
ace.unk1 mustEqual 8
|
||||
|
|
@ -299,9 +299,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4777.633f
|
||||
drop.pos.coord.y mustEqual 5485.4062f
|
||||
drop.pos.coord.z mustEqual 85.8125f
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.yaw mustEqual 27
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 14.0625f
|
||||
drop.obj.isInstanceOf[CommandDetonaterData] mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
|
|
@ -321,9 +321,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4684.7344f
|
||||
drop.pos.coord.y mustEqual 5547.4844f
|
||||
drop.pos.coord.z mustEqual 83.765625f
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.yaw mustEqual 89
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 199.6875f
|
||||
drop.obj.isInstanceOf[AmmoBoxData] mustEqual true
|
||||
val box = drop.obj.asInstanceOf[AmmoBoxData]
|
||||
box.unk mustEqual 0
|
||||
|
|
@ -345,9 +345,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4691.1953f
|
||||
drop.pos.coord.y mustEqual 5537.039f
|
||||
drop.pos.coord.z mustEqual 65.484375f
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.yaw mustEqual 32
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 0f
|
||||
drop.obj.isInstanceOf[WeaponData] mustEqual true
|
||||
val wep = drop.obj.asInstanceOf[WeaponData]
|
||||
wep.unk1 mustEqual 4
|
||||
|
|
@ -377,9 +377,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
drop.pos.coord.x mustEqual 4789.133f
|
||||
drop.pos.coord.y mustEqual 5522.3125f
|
||||
drop.pos.coord.z mustEqual 72.3125f
|
||||
drop.pos.roll mustEqual 0
|
||||
drop.pos.pitch mustEqual 0
|
||||
drop.pos.yaw mustEqual 51
|
||||
drop.pos.orient.x mustEqual 0f
|
||||
drop.pos.orient.y mustEqual 0f
|
||||
drop.pos.orient.z mustEqual 306.5625f
|
||||
drop.obj.isInstanceOf[WeaponData] mustEqual true
|
||||
val wep = drop.obj.asInstanceOf[WeaponData]
|
||||
wep.unk1 mustEqual 2
|
||||
|
|
@ -417,9 +417,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
dropped.pos.coord.x mustEqual 4675.039f
|
||||
dropped.pos.coord.y mustEqual 5506.953f
|
||||
dropped.pos.coord.z mustEqual 72.703125f
|
||||
dropped.pos.roll mustEqual 0
|
||||
dropped.pos.pitch mustEqual 0
|
||||
dropped.pos.yaw mustEqual 78
|
||||
dropped.pos.orient.x mustEqual 0f
|
||||
dropped.pos.orient.y mustEqual 0f
|
||||
dropped.pos.orient.z mustEqual 230.625f
|
||||
dropped.obj.isInstanceOf[REKData] mustEqual true
|
||||
val rek = dropped.obj.asInstanceOf[REKData]
|
||||
rek.unk1 mustEqual 8
|
||||
|
|
@ -443,9 +443,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
boomer.deploy.pos.coord.x mustEqual 4704.172f
|
||||
boomer.deploy.pos.coord.y mustEqual 5546.4375f
|
||||
boomer.deploy.pos.coord.z mustEqual 82.234375f
|
||||
boomer.deploy.pos.roll mustEqual 0
|
||||
boomer.deploy.pos.pitch mustEqual 0
|
||||
boomer.deploy.pos.yaw mustEqual 63
|
||||
boomer.deploy.pos.orient.x mustEqual 0f
|
||||
boomer.deploy.pos.orient.y mustEqual 0f
|
||||
boomer.deploy.pos.orient.z mustEqual 272.8125f
|
||||
boomer.deploy.unk mustEqual 0
|
||||
boomer.deploy.player_guid mustEqual PlanetSideGUID(4145)
|
||||
case _ =>
|
||||
|
|
@ -466,9 +466,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
turret.deploy.pos.coord.x mustEqual 4577.7812f
|
||||
turret.deploy.pos.coord.y mustEqual 5624.828f
|
||||
turret.deploy.pos.coord.z mustEqual 72.046875f
|
||||
turret.deploy.pos.roll mustEqual 0
|
||||
turret.deploy.pos.pitch mustEqual 127
|
||||
turret.deploy.pos.yaw mustEqual 66
|
||||
turret.deploy.pos.orient.x mustEqual 0f
|
||||
turret.deploy.pos.orient.y mustEqual 2.8125f
|
||||
turret.deploy.pos.orient.z mustEqual 264.375f
|
||||
turret.deploy.faction mustEqual PlanetSideEmpire.NC
|
||||
turret.deploy.unk mustEqual 12
|
||||
turret.deploy.player_guid mustEqual PlanetSideGUID(3871)
|
||||
|
|
@ -492,9 +492,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
turret.deploy.pos.coord.x mustEqual 4527.633f
|
||||
turret.deploy.pos.coord.y mustEqual 6271.3594f
|
||||
turret.deploy.pos.coord.z mustEqual 70.265625f
|
||||
turret.deploy.pos.roll mustEqual 0
|
||||
turret.deploy.pos.pitch mustEqual 0
|
||||
turret.deploy.pos.yaw mustEqual 105
|
||||
turret.deploy.pos.orient.x mustEqual 0f
|
||||
turret.deploy.pos.orient.y mustEqual 0f
|
||||
turret.deploy.pos.orient.z mustEqual 154.6875f
|
||||
turret.deploy.faction mustEqual PlanetSideEmpire.VS
|
||||
turret.deploy.unk mustEqual 4
|
||||
turret.deploy.player_guid mustEqual PlanetSideGUID(4232)
|
||||
|
|
@ -533,9 +533,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
trap.deploy.pos.coord.x mustEqual 3572.4453f
|
||||
trap.deploy.pos.coord.y mustEqual 3277.9766f
|
||||
trap.deploy.pos.coord.z mustEqual 114.0f
|
||||
trap.deploy.pos.roll mustEqual 0
|
||||
trap.deploy.pos.pitch mustEqual 0
|
||||
trap.deploy.pos.yaw mustEqual 0
|
||||
trap.deploy.pos.orient.x mustEqual 0f
|
||||
trap.deploy.pos.orient.y mustEqual 0f
|
||||
trap.deploy.pos.orient.z mustEqual 90.0f
|
||||
trap.deploy.faction mustEqual PlanetSideEmpire.VS
|
||||
trap.deploy.unk mustEqual 4
|
||||
trap.health mustEqual 255
|
||||
|
|
@ -558,9 +558,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
aegis.deploy.pos.coord.x mustEqual 3571.2266f
|
||||
aegis.deploy.pos.coord.y mustEqual 3278.0938f
|
||||
aegis.deploy.pos.coord.z mustEqual 114.0f
|
||||
aegis.deploy.pos.roll mustEqual 0
|
||||
aegis.deploy.pos.pitch mustEqual 0
|
||||
aegis.deploy.pos.yaw mustEqual 0
|
||||
aegis.deploy.pos.orient.x mustEqual 0f
|
||||
aegis.deploy.pos.orient.y mustEqual 0f
|
||||
aegis.deploy.pos.orient.z mustEqual 90.0f
|
||||
aegis.deploy.faction mustEqual PlanetSideEmpire.VS
|
||||
aegis.deploy.unk mustEqual 4
|
||||
aegis.health mustEqual 255
|
||||
|
|
@ -583,9 +583,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
omft.deploy.pos.coord.x mustEqual 3567.1406f
|
||||
omft.deploy.pos.coord.y mustEqual 2988.0078f
|
||||
omft.deploy.pos.coord.z mustEqual 71.84375f
|
||||
omft.deploy.pos.roll mustEqual 0
|
||||
omft.deploy.pos.pitch mustEqual 0
|
||||
omft.deploy.pos.yaw mustEqual 94
|
||||
omft.deploy.pos.orient.x mustEqual 0f
|
||||
omft.deploy.pos.orient.y mustEqual 0f
|
||||
omft.deploy.pos.orient.z mustEqual 185.625f
|
||||
omft.deploy.faction mustEqual PlanetSideEmpire.VS
|
||||
omft.deploy.unk mustEqual 4
|
||||
omft.deploy.player_guid mustEqual PlanetSideGUID(2502)
|
||||
|
|
@ -666,9 +666,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
pc.appearance.pos.coord.x mustEqual 3674.8438f
|
||||
pc.appearance.pos.coord.y mustEqual 2726.789f
|
||||
pc.appearance.pos.coord.z mustEqual 91.15625f
|
||||
pc.appearance.pos.roll mustEqual 0
|
||||
pc.appearance.pos.pitch mustEqual 0
|
||||
pc.appearance.pos.yaw mustEqual 9
|
||||
pc.appearance.pos.orient.x mustEqual 0f
|
||||
pc.appearance.pos.orient.y mustEqual 0f
|
||||
pc.appearance.pos.orient.z mustEqual 64.6875f
|
||||
pc.appearance.pos.vel.isDefined mustEqual true
|
||||
pc.appearance.pos.vel.get.x mustEqual 1.4375f
|
||||
pc.appearance.pos.vel.get.y mustEqual -0.4375f
|
||||
|
|
@ -684,7 +684,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
pc.appearance.exosuit mustEqual ExoSuitType.Reinforced
|
||||
pc.appearance.outfit_name mustEqual "Black Beret Armoured Corps"
|
||||
pc.appearance.outfit_logo mustEqual 23
|
||||
pc.appearance.facingPitch mustEqual 7
|
||||
pc.appearance.facingPitch mustEqual 340.3125f
|
||||
pc.appearance.facingYawUpper mustEqual 0
|
||||
pc.appearance.lfs mustEqual false
|
||||
pc.appearance.grenade_state mustEqual GrenadeState.None
|
||||
|
|
@ -765,9 +765,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
pc.appearance.pos.coord.x mustEqual 4629.8906f
|
||||
pc.appearance.pos.coord.y mustEqual 6316.4453f
|
||||
pc.appearance.pos.coord.z mustEqual 54.734375f
|
||||
pc.appearance.pos.roll mustEqual 0
|
||||
pc.appearance.pos.pitch mustEqual 0
|
||||
pc.appearance.pos.yaw mustEqual 115
|
||||
pc.appearance.pos.orient.x mustEqual 0f
|
||||
pc.appearance.pos.orient.y mustEqual 0f
|
||||
pc.appearance.pos.orient.z mustEqual 126.5625f
|
||||
pc.appearance.pos.vel.isDefined mustEqual false
|
||||
pc.appearance.basic_appearance.name mustEqual "Angello"
|
||||
pc.appearance.basic_appearance.faction mustEqual PlanetSideEmpire.VS
|
||||
|
|
@ -781,7 +781,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
pc.appearance.outfit_name mustEqual "Original District"
|
||||
pc.appearance.outfit_logo mustEqual 23
|
||||
pc.appearance.facingPitch mustEqual 0
|
||||
pc.appearance.facingYawUpper mustEqual 192
|
||||
pc.appearance.facingYawUpper mustEqual 180.0f
|
||||
pc.appearance.lfs mustEqual false
|
||||
pc.appearance.grenade_state mustEqual GrenadeState.None
|
||||
pc.appearance.is_cloaking mustEqual false
|
||||
|
|
@ -811,13 +811,15 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (striker projectile)" in {
|
||||
val obj = TrackedProjectileData.striker(
|
||||
PlacementData(4644.5938f, 5472.0938f, 82.375f, 0, 245, 227),
|
||||
PlacementData(4644.5938f, 5472.0938f, 82.375f, 0f, 30.9375f, 171.5625f),
|
||||
0
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.striker_missile_targeting_projectile, PlanetSideGUID(40192), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_striker_projectile
|
||||
pkt.toBitVector.take(132) mustEqual string_striker_projectile.toBitVector.take(132)
|
||||
pkt.toBitVector.drop(133).take(7) mustEqual string_striker_projectile.toBitVector.drop(133).take(7)
|
||||
pkt.toBitVector.drop(141) mustEqual string_striker_projectile.toBitVector.drop(141)
|
||||
}
|
||||
|
||||
"encode (implant interface)" in {
|
||||
|
|
@ -830,7 +832,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (order terminal a)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(4579.3438f, 5615.0703f, 72.953125f, 0, 0, 125),
|
||||
PlacementData(4579.3438f, 5615.0703f, 72.953125f, 0f, 0f, 98.4375f),
|
||||
CommonTerminalData(PlanetSideEmpire.NC)
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.order_terminala, PlanetSideGUID(3827), obj)
|
||||
|
|
@ -893,7 +895,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (capture flag)" in {
|
||||
val obj = CaptureFlagData(PlacementData(3912.0312f, 5169.4375f, 59.96875f, 0, 0, 15), PlanetSideEmpire.NC, 21, 4, 2838, 9)
|
||||
val obj = CaptureFlagData(PlacementData(3912.0312f, 5169.4375f, 59.96875f, 0f, 0f, 47.8125f), PlanetSideEmpire.NC, 21, 4, 2838, 9)
|
||||
val msg = ObjectCreateMessage(ObjectClass.capture_flag, PlanetSideGUID(4330), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
|
|
@ -902,7 +904,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (ace, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4708.461f, 5547.539f, 72.703125f), 0, 0, 91),
|
||||
PlacementData(4708.461f, 5547.539f, 72.703125f, 0f, 0f, 194.0625f),
|
||||
ACEData(8, 8)
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.ace, PlanetSideGUID(4388), obj)
|
||||
|
|
@ -913,7 +915,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (detonator, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4777.633f, 5485.4062f, 85.8125f), 0, 0, 27),
|
||||
PlacementData(4777.633f, 5485.4062f, 85.8125f, 0f, 0f, 14.0625f),
|
||||
CommandDetonaterData()
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.command_detonater, PlanetSideGUID(3682), obj)
|
||||
|
|
@ -924,7 +926,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (shotgun shells, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4684.7344f, 5547.4844f, 83.765625f), 0, 0, 89),
|
||||
PlacementData(4684.7344f, 5547.4844f, 83.765625f, 0f, 0f, 199.6875f),
|
||||
AmmoBoxData()
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.shotgun_shell, PlanetSideGUID(3453), obj)
|
||||
|
|
@ -935,7 +937,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (lasher, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4691.1953f, 5537.039f, 65.484375f), 0, 0, 32),
|
||||
PlacementData(4691.1953f, 5537.039f, 65.484375f, 0.0f, 0.0f, 0.0f),
|
||||
WeaponData(4, 0, ObjectClass.energy_cell, PlanetSideGUID(3268), 0, AmmoBoxData())
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.lasher, PlanetSideGUID(3074), obj)
|
||||
|
|
@ -946,7 +948,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (punisher, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4789.133f, 5522.3125f, 72.3125f), 0, 0, 51),
|
||||
PlacementData(4789.133f, 5522.3125f, 72.3125f, 0f, 0f, 306.5625f),
|
||||
WeaponData(2, 0, 0,
|
||||
AmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(3528), 0, AmmoBoxData()) ::
|
||||
AmmoBoxData(ObjectClass.rocket, PlanetSideGUID(3031), 1, AmmoBoxData()) ::
|
||||
|
|
@ -961,7 +963,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
|
||||
"encode (REK, dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(Vector3(4675.039f, 5506.953f, 72.703125f), 0, 0, 78),
|
||||
PlacementData(4675.039f, 5506.953f, 72.703125f, 0f, 0f, 230.625f),
|
||||
REKData(8, 0, 3)
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.remote_electronics_kit, PlanetSideGUID(4355), obj)
|
||||
|
|
@ -973,7 +975,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (boomer)" in {
|
||||
val obj = SmallDeployableData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(4704.172f, 5546.4375f, 82.234375f), 0, 0, 63),
|
||||
PlacementData(4704.172f, 5546.4375f, 82.234375f, 0f, 0f, 272.8125f),
|
||||
PlanetSideEmpire.TR, 0, PlanetSideGUID(4145)
|
||||
)
|
||||
)
|
||||
|
|
@ -986,7 +988,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (spitfire, short)" in {
|
||||
val obj = SmallTurretData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(4577.7812f, 5624.828f, 72.046875f), 0, 127, 66),
|
||||
PlacementData(4577.7812f, 5624.828f, 72.046875f, 0f, 2.8125f, 264.375f),
|
||||
PlanetSideEmpire.NC, 12, PlanetSideGUID(3871)
|
||||
),
|
||||
255 //sets to 0
|
||||
|
|
@ -1004,7 +1006,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (spitfire)" in {
|
||||
val obj = SmallTurretData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(4527.633f, 6271.3594f, 70.265625f), 0, 0, 105),
|
||||
PlacementData(4527.633f, 6271.3594f, 70.265625f, 0f, 0f, 154.6875f),
|
||||
PlanetSideEmpire.VS, 4, PlanetSideGUID(4232)
|
||||
),
|
||||
255,
|
||||
|
|
@ -1023,7 +1025,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (trap)" in {
|
||||
val obj = TRAPData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(3572.4453f, 3277.9766f, 114.0f), 0, 0, 0),
|
||||
PlacementData(3572.4453f, 3277.9766f, 114.0f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 4, PlanetSideGUID(2502)
|
||||
),
|
||||
255
|
||||
|
|
@ -1041,7 +1043,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (aegis)" in {
|
||||
val obj = AegisShieldGeneratorData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(3571.2266f, 3278.0938f, 114.0f), 0, 0, 0),
|
||||
PlacementData(3571.2266f, 3278.0938f, 114.0f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 4, PlanetSideGUID(2366)
|
||||
),
|
||||
255
|
||||
|
|
@ -1055,7 +1057,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (orion)" in {
|
||||
val obj = OneMannedFieldTurretData(
|
||||
CommonFieldData(
|
||||
PlacementData(Vector3(3567.1406f, 2988.0078f, 71.84375f), 0, 0, 94),
|
||||
PlacementData(3567.1406f, 2988.0078f, 71.84375f, 0f, 0f, 185.625f),
|
||||
PlanetSideEmpire.VS, 4, PlanetSideGUID(2502)
|
||||
),
|
||||
255,
|
||||
|
|
@ -1091,7 +1093,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
CharacterAppearanceData(
|
||||
PlacementData(
|
||||
Vector3(3674.8438f, 2726.789f, 91.15625f),
|
||||
0, 0, 9,
|
||||
Vector3(0f, 0f, 64.6875f),
|
||||
Some(Vector3(1.4375f, -0.4375f, 0f))
|
||||
),
|
||||
BasicCharacterData(
|
||||
|
|
@ -1108,7 +1110,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"Black Beret Armoured Corps",
|
||||
23,
|
||||
false,
|
||||
7, 0,
|
||||
340.3125f, 0f,
|
||||
false,
|
||||
GrenadeState.None,
|
||||
false, false, false,
|
||||
|
|
@ -1150,7 +1152,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"encode (character, backpack)" in {
|
||||
val obj = CharacterData(
|
||||
CharacterAppearanceData(
|
||||
PlacementData(4629.8906f, 6316.4453f, 54.734375f, 0, 0, 115),
|
||||
PlacementData(4629.8906f, 6316.4453f, 54.734375f, 0f, 0f, 126.5625f),
|
||||
BasicCharacterData(
|
||||
"Angello",
|
||||
PlanetSideEmpire.VS,
|
||||
|
|
@ -1165,7 +1167,7 @@ class ObjectCreateMessageTest extends Specification {
|
|||
"Original District",
|
||||
23,
|
||||
true, //backpack
|
||||
0, 192,
|
||||
0f, 180.0f,
|
||||
false,
|
||||
GrenadeState.None,
|
||||
false, false, false,
|
||||
|
|
@ -1191,8 +1193,9 @@ class ObjectCreateMessageTest extends Specification {
|
|||
val ori_bitv = string_character_backpack.toBitVector
|
||||
pkt_bitv.take(300) mustEqual ori_bitv.take(300) //skip 2
|
||||
pkt_bitv.drop(302).take(14) mustEqual ori_bitv.drop(302).take(14) //skip 126
|
||||
pkt_bitv.drop(442).take(317) mustEqual ori_bitv.drop(442).take(317) //skip 2
|
||||
pkt_bitv.drop(761).take(155) mustEqual ori_bitv.drop(761).take(155) //skip 1
|
||||
pkt_bitv.drop(442).take(305) mustEqual ori_bitv.drop(442).take(305) //skip 1
|
||||
pkt_bitv.drop(748).take(9) mustEqual ori_bitv.drop(748).take(9) // skip 2
|
||||
pkt_bitv.drop(759).take(157) mustEqual ori_bitv.drop(759).take(157) //skip 1
|
||||
pkt_bitv.drop(917) mustEqual ori_bitv.drop(917)
|
||||
//TODO work on CharacterData to make this pass as a single stream
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
fury.basic.pos.coord.x mustEqual 6531.961f
|
||||
fury.basic.pos.coord.y mustEqual 1872.1406f
|
||||
fury.basic.pos.coord.z mustEqual 24.734375f
|
||||
fury.basic.pos.roll mustEqual 0
|
||||
fury.basic.pos.pitch mustEqual 0
|
||||
fury.basic.pos.yaw mustEqual 33
|
||||
fury.basic.pos.orient.x mustEqual 0f
|
||||
fury.basic.pos.orient.y mustEqual 0f
|
||||
fury.basic.pos.orient.z mustEqual 357.1875f
|
||||
fury.basic.pos.vel.isDefined mustEqual false
|
||||
fury.basic.faction mustEqual PlanetSideEmpire.VS
|
||||
fury.basic.unk mustEqual 4
|
||||
|
|
@ -78,9 +78,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
ant.basic.pos.coord.x mustEqual 3674.8438f
|
||||
ant.basic.pos.coord.y mustEqual 2726.789f
|
||||
ant.basic.pos.coord.z mustEqual 91.15625f
|
||||
ant.basic.pos.roll mustEqual 0
|
||||
ant.basic.pos.pitch mustEqual 0
|
||||
ant.basic.pos.yaw mustEqual 0
|
||||
ant.basic.pos.orient.x mustEqual 0f
|
||||
ant.basic.pos.orient.y mustEqual 0f
|
||||
ant.basic.pos.orient.z mustEqual 90.0f
|
||||
ant.basic.faction mustEqual PlanetSideEmpire.VS
|
||||
ant.basic.unk mustEqual 4
|
||||
ant.basic.player_guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -104,9 +104,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
lightning.basic.pos.coord.x mustEqual 3674.8438f
|
||||
lightning.basic.pos.coord.y mustEqual 2726.789f
|
||||
lightning.basic.pos.coord.z mustEqual 91.15625f
|
||||
lightning.basic.pos.roll mustEqual 0
|
||||
lightning.basic.pos.pitch mustEqual 0
|
||||
lightning.basic.pos.yaw mustEqual 0
|
||||
lightning.basic.pos.orient.x mustEqual 0f
|
||||
lightning.basic.pos.orient.y mustEqual 0f
|
||||
lightning.basic.pos.orient.z mustEqual 90.0f
|
||||
lightning.basic.faction mustEqual PlanetSideEmpire.VS
|
||||
lightning.basic.unk mustEqual 4
|
||||
lightning.basic.player_guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -155,9 +155,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
deliverer.basic.pos.coord.x mustEqual 6531.961f
|
||||
deliverer.basic.pos.coord.y mustEqual 1872.1406f
|
||||
deliverer.basic.pos.coord.z mustEqual 24.734375f
|
||||
deliverer.basic.pos.roll mustEqual 0
|
||||
deliverer.basic.pos.pitch mustEqual 0
|
||||
deliverer.basic.pos.yaw mustEqual 33
|
||||
deliverer.basic.pos.orient.x mustEqual 0f
|
||||
deliverer.basic.pos.orient.y mustEqual 0f
|
||||
deliverer.basic.pos.orient.z mustEqual 357.1875f
|
||||
deliverer.basic.faction mustEqual PlanetSideEmpire.NC
|
||||
deliverer.basic.unk mustEqual 4
|
||||
deliverer.basic.player_guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -221,9 +221,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
ams.basic.pos.coord.x mustEqual 3674.0f
|
||||
ams.basic.pos.coord.y mustEqual 2726.789f
|
||||
ams.basic.pos.coord.z mustEqual 91.15625f
|
||||
ams.basic.pos.roll mustEqual 0
|
||||
ams.basic.pos.pitch mustEqual 0
|
||||
ams.basic.pos.yaw mustEqual 0
|
||||
ams.basic.pos.orient.x mustEqual 0f
|
||||
ams.basic.pos.orient.y mustEqual 0f
|
||||
ams.basic.pos.orient.z mustEqual 90.0f
|
||||
ams.basic.faction mustEqual PlanetSideEmpire.VS
|
||||
ams.basic.unk mustEqual 0
|
||||
ams.basic.player_guid mustEqual PlanetSideGUID(34082)
|
||||
|
|
@ -253,9 +253,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
dams.pos.coord.x mustEqual 3674.0f
|
||||
dams.pos.coord.y mustEqual 2726.789f
|
||||
dams.pos.coord.z mustEqual 91.15625f
|
||||
dams.pos.roll mustEqual 0
|
||||
dams.pos.pitch mustEqual 0
|
||||
dams.pos.yaw mustEqual 0
|
||||
dams.pos.orient.x mustEqual 0f
|
||||
dams.pos.orient.y mustEqual 0f
|
||||
dams.pos.orient.z mustEqual 90.0f
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -274,9 +274,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
switchblade.basic.pos.coord.x mustEqual 6531.961f
|
||||
switchblade.basic.pos.coord.y mustEqual 1872.1406f
|
||||
switchblade.basic.pos.coord.z mustEqual 24.734375f
|
||||
switchblade.basic.pos.roll mustEqual 0
|
||||
switchblade.basic.pos.pitch mustEqual 0
|
||||
switchblade.basic.pos.yaw mustEqual 33
|
||||
switchblade.basic.pos.orient.x mustEqual 0f
|
||||
switchblade.basic.pos.orient.y mustEqual 0f
|
||||
switchblade.basic.pos.orient.z mustEqual 357.1875f
|
||||
switchblade.basic.faction mustEqual PlanetSideEmpire.VS
|
||||
switchblade.basic.unk mustEqual 4
|
||||
switchblade.health mustEqual 255
|
||||
|
|
@ -321,9 +321,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
droppod.basic.pos.coord.x mustEqual 5108.0f
|
||||
droppod.basic.pos.coord.y mustEqual 6164.0f
|
||||
droppod.basic.pos.coord.z mustEqual 1023.9844f
|
||||
droppod.basic.pos.roll mustEqual 0
|
||||
droppod.basic.pos.pitch mustEqual 0
|
||||
droppod.basic.pos.yaw mustEqual 0
|
||||
droppod.basic.pos.orient.x mustEqual 0f
|
||||
droppod.basic.pos.orient.y mustEqual 0f
|
||||
droppod.basic.pos.orient.z mustEqual 90.0f
|
||||
droppod.basic.unk mustEqual 4
|
||||
droppod.basic.player_guid mustEqual PlanetSideGUID(0)
|
||||
droppod.burn mustEqual false
|
||||
|
|
@ -366,9 +366,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
shuttle.pos.get.coord.x mustEqual 5610.0156f
|
||||
shuttle.pos.get.coord.y mustEqual 4255.258f
|
||||
shuttle.pos.get.coord.z mustEqual 134.1875f
|
||||
shuttle.pos.get.roll mustEqual 0
|
||||
shuttle.pos.get.pitch mustEqual 0
|
||||
shuttle.pos.get.yaw mustEqual 96
|
||||
shuttle.pos.get.orient.x mustEqual 0f
|
||||
shuttle.pos.get.orient.y mustEqual 0f
|
||||
shuttle.pos.get.orient.z mustEqual 180.0f
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -377,7 +377,7 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
"encode (fury)" in {
|
||||
val obj = VehicleData(
|
||||
CommonFieldData(
|
||||
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0, 0, 33),
|
||||
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
|
||||
PlanetSideEmpire.VS, 4
|
||||
),
|
||||
255,
|
||||
|
|
@ -394,7 +394,7 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
"encode (ant)" in {
|
||||
val obj = ANTData(
|
||||
CommonFieldData(
|
||||
PlacementData(3674.8438f, 2726.789f, 91.15625f),
|
||||
PlacementData(3674.8438f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 4
|
||||
),
|
||||
255,
|
||||
|
|
@ -409,7 +409,7 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
"encode (lightning)" in {
|
||||
val obj = VehicleData(
|
||||
CommonFieldData(
|
||||
PlacementData(3674.8438f, 2726.789f, 91.15625f),
|
||||
PlacementData(3674.8438f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 4
|
||||
),
|
||||
255,
|
||||
|
|
@ -423,10 +423,10 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
pkt mustEqual string_lightning
|
||||
}
|
||||
|
||||
"encode (deliverer)" in {
|
||||
"encode (medium transport)" in {
|
||||
val obj = VehicleData(
|
||||
CommonFieldData(
|
||||
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0, 0, 33),
|
||||
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
|
||||
PlanetSideEmpire.NC, 4
|
||||
),
|
||||
0,
|
||||
|
|
@ -455,7 +455,8 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
|
||||
"encode (ams)" in {
|
||||
val obj = AMSData(
|
||||
CommonFieldData(PlacementData(3674.0f, 2726.789f, 91.15625f, 0, 0, 0),
|
||||
CommonFieldData(
|
||||
PlacementData(3674.0f, 2726.789f, 91.15625f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 0,
|
||||
PlanetSideGUID(34082)
|
||||
),
|
||||
|
|
@ -476,17 +477,19 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (ams, destroyed)" in {
|
||||
val obj = DestroyedVehicleData(PlacementData(3674.0f, 2726.789f, 91.15625f))
|
||||
val obj = DestroyedVehicleData(PlacementData(3674.0f, 2726.789f, 91.15625f, 0f, 0f, 90.0f))
|
||||
val msg = ObjectCreateMessage(ObjectClass.ams_destroyed, PlanetSideGUID(4157), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_ams_destroyed
|
||||
}
|
||||
|
||||
"encode (switchblade(" in {
|
||||
"encode (switchblade)" in {
|
||||
val obj = Vehicle2Data(
|
||||
CommonFieldData(PlacementData(6531.961f, 1872.1406f, 24.734375f ,0 ,0 ,33),
|
||||
PlanetSideEmpire.VS, 4
|
||||
CommonFieldData(
|
||||
PlacementData(6531.961f, 1872.1406f, 24.734375f, 0f, 0f, 357.1875f),
|
||||
PlanetSideEmpire.VS,
|
||||
4
|
||||
),
|
||||
255,
|
||||
DriveState.Mobile,
|
||||
|
|
@ -503,8 +506,9 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
"encode (droppod)" in {
|
||||
val obj = DroppodData(
|
||||
CommonFieldData(
|
||||
PlacementData(5108.0f, 6164.0f, 1023.9844f),
|
||||
PlanetSideEmpire.VS, 4
|
||||
PlacementData(5108.0f, 6164.0f, 1023.9844f, 0f, 0f, 90.0f),
|
||||
PlanetSideEmpire.VS,
|
||||
4
|
||||
)
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.droppod, PlanetSideGUID(3595), obj)
|
||||
|
|
@ -522,7 +526,7 @@ class ObjectCreateMessageVehiclesTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (shuttle 2)" in {
|
||||
val obj = OrbitalShuttleData(PlacementData(5610.0156f, 4255.258f, 134.1875f, 0, 0, 96), PlanetSideEmpire.VS)
|
||||
val obj = OrbitalShuttleData(PlacementData(5610.0156f, 4255.258f, 134.1875f, 0f, 0f, 180.0f), PlanetSideEmpire.VS)
|
||||
val msg = ObjectCreateMessage(ObjectClass.orbital_shuttle, PlanetSideGUID(1127), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ class ObjectDetachMessageTest extends Specification {
|
|||
pos.x mustEqual 3567.1406f
|
||||
pos.y mustEqual 2988.0078f
|
||||
pos.z mustEqual 71.84375f
|
||||
roll mustEqual 0
|
||||
pitch mustEqual 0
|
||||
yaw mustEqual 64
|
||||
roll mustEqual 0f
|
||||
pitch mustEqual 0f
|
||||
yaw mustEqual 270f
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), 0, 0, 64)
|
||||
val msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), 0f, 0f, 270f)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ class PlayerStateMessageTest extends Specification {
|
|||
pos.y mustEqual 5981.414f
|
||||
pos.z mustEqual 44.875f
|
||||
vel.isDefined mustEqual false
|
||||
facingYaw mustEqual 31
|
||||
facingPitch mustEqual 0
|
||||
facingUpper mustEqual 0
|
||||
facingYaw mustEqual 2.8125f
|
||||
facingPitch mustEqual 0f
|
||||
facingUpper mustEqual 0f
|
||||
unk1 mustEqual 83
|
||||
crouching mustEqual false
|
||||
jumping mustEqual false
|
||||
|
|
@ -41,9 +41,9 @@ class PlayerStateMessageTest extends Specification {
|
|||
pos.y mustEqual 5981.414f
|
||||
pos.z mustEqual 44.875f
|
||||
vel.isDefined mustEqual false
|
||||
facingYaw mustEqual 31
|
||||
facingPitch mustEqual 0
|
||||
facingUpper mustEqual 0
|
||||
facingYaw mustEqual 2.8125f
|
||||
facingPitch mustEqual 0f
|
||||
facingUpper mustEqual 0f
|
||||
unk1 mustEqual 83
|
||||
crouching mustEqual false
|
||||
jumping mustEqual true
|
||||
|
|
@ -65,9 +65,9 @@ class PlayerStateMessageTest extends Specification {
|
|||
vel.get.x mustEqual 2.53125f
|
||||
vel.get.y mustEqual 6.5625f
|
||||
vel.get.z mustEqual 0.0f
|
||||
facingYaw mustEqual 24
|
||||
facingPitch mustEqual 4
|
||||
facingUpper mustEqual 0
|
||||
facingYaw mustEqual 22.5f
|
||||
facingPitch mustEqual 348.75f
|
||||
facingUpper mustEqual 0f
|
||||
unk1 mustEqual 165
|
||||
crouching mustEqual false
|
||||
jumping mustEqual false
|
||||
|
|
@ -83,7 +83,7 @@ class PlayerStateMessageTest extends Specification {
|
|||
PlanetSideGUID(1696),
|
||||
Vector3(4003.7422f, 5981.414f, 44.875f),
|
||||
None,
|
||||
31, 0, 0, 83,
|
||||
2.8125f, 0f, 0f, 83,
|
||||
false, false, false, false)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
pkt mustEqual string_short
|
||||
|
|
@ -94,7 +94,7 @@ class PlayerStateMessageTest extends Specification {
|
|||
PlanetSideGUID(1696),
|
||||
Vector3(4003.7422f, 5981.414f, 44.875f),
|
||||
None,
|
||||
31, 0, 0, 83,
|
||||
2.8125f, 0f, 0f, 83,
|
||||
false, true, false, true)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
pkt mustEqual string_mod
|
||||
|
|
@ -105,7 +105,7 @@ class PlayerStateMessageTest extends Specification {
|
|||
PlanetSideGUID(1696),
|
||||
Vector3(4008.6016f, 5987.6016f, 44.1875f),
|
||||
Some(Vector3(2.53125f, 6.5625f, 0f)),
|
||||
24, 4, 0, 165,
|
||||
22.5f, 348.75f, 0f, 165,
|
||||
false, false, false, false)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
pkt mustEqual string_vel
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ class PlayerStateMessageUpstreamTest extends Specification {
|
|||
avatar_guid mustEqual PlanetSideGUID(75)
|
||||
pos mustEqual Vector3(3694.1094f, 2735.4531f, 90.84375f)
|
||||
vel mustEqual Some(Vector3(4.375f, 2.59375f, 0.0f))
|
||||
facingYaw mustEqual 10
|
||||
facingPitch mustEqual 3
|
||||
facingYawUpper mustEqual 0
|
||||
facingYaw mustEqual 61.875f
|
||||
facingPitch mustEqual 351.5625f
|
||||
facingYawUpper mustEqual 0.0f
|
||||
seq_time mustEqual 136
|
||||
unk1 mustEqual 0
|
||||
is_crouching mustEqual false
|
||||
|
|
@ -33,7 +33,7 @@ class PlayerStateMessageUpstreamTest extends Specification {
|
|||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = PlayerStateMessageUpstream(PlanetSideGUID(75), Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 10, 3, 0, 136, 0, false, false, false, false, 112, 0)
|
||||
val msg = PlayerStateMessageUpstream(PlanetSideGUID(75), Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 61.875f, 351.5625f, 0.0f, 136, 0, false, false, false, false, 112, 0)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import scodec.bits._
|
|||
|
||||
class PlayerStateShiftMessageTest extends Specification {
|
||||
val string_short = hex"BE 68"
|
||||
val string_pos = hex"BE 95 A0 89 13 91 B8 B0 BF F0"
|
||||
val string_pos = hex"BE 95 A0 89 13 91 B8 B0 B7 F0" //orig: ... B0 BF F0
|
||||
val string_posAndVel = hex"BE AE 01 29 CD 59 B9 40 C0 EA D4 00 0F 86 40"
|
||||
|
||||
"decode (short)" in {
|
||||
|
|
@ -31,7 +31,7 @@ class PlayerStateShiftMessageTest extends Specification {
|
|||
state.get.pos.x mustEqual 4624.703f
|
||||
state.get.pos.y mustEqual 5922.1484f
|
||||
state.get.pos.z mustEqual 46.171875f
|
||||
state.get.viewYawLim mustEqual 255
|
||||
state.get.viewYawLim mustEqual 92.8125f
|
||||
state.get.vel.isDefined mustEqual false
|
||||
unk.isDefined mustEqual false
|
||||
case _ =>
|
||||
|
|
@ -47,7 +47,7 @@ class PlayerStateShiftMessageTest extends Specification {
|
|||
state.get.pos.x mustEqual 4645.75f
|
||||
state.get.pos.y mustEqual 5811.6016f
|
||||
state.get.pos.z mustEqual 50.3125f
|
||||
state.get.viewYawLim mustEqual 14
|
||||
state.get.viewYawLim mustEqual 50.625f
|
||||
state.get.vel.isDefined mustEqual true
|
||||
state.get.vel.get.x mustEqual 2.8125f
|
||||
state.get.vel.get.y mustEqual -8.0f
|
||||
|
|
@ -66,14 +66,14 @@ class PlayerStateShiftMessageTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (pos)" in {
|
||||
val msg = PlayerStateShiftMessage(ShiftState(1, Vector3(4624.703f, 5922.1484f, 46.171875f), 255))
|
||||
val msg = PlayerStateShiftMessage(ShiftState(1, Vector3(4624.703f, 5922.1484f, 46.171875f), 92.8125f))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_pos
|
||||
}
|
||||
|
||||
"encode (pos and vel)" in {
|
||||
val msg = PlayerStateShiftMessage(ShiftState(2, Vector3(4645.75f, 5811.6016f, 50.3125f), 14, Vector3(2.8125f, -8.0f, 0.375f)))
|
||||
val msg = PlayerStateShiftMessage(ShiftState(2, Vector3(4645.75f, 5811.6016f, 50.3125f), 50.625f, Vector3(2.8125f, -8.0f, 0.375f)))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_posAndVel
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ class VehicleStateMessageTest extends Specification {
|
|||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case VehicleStateMessage(guid, unk1, pos, roll, pitch, yaw, vel, unk2, unk3, unk4, wheel, unk5, unk6) =>
|
||||
case VehicleStateMessage(guid, unk1, pos, ang, vel, unk2, unk3, unk4, wheel, unk5, unk6) =>
|
||||
guid mustEqual PlanetSideGUID(413)
|
||||
unk1 mustEqual 0
|
||||
pos.x mustEqual 3674.8438f
|
||||
pos.y mustEqual 2726.789f
|
||||
pos.z mustEqual 91.09375f
|
||||
roll mustEqual 359.29688f
|
||||
pitch mustEqual 1.0546875f
|
||||
yaw mustEqual 90.35156f
|
||||
ang.x mustEqual 359.29688f
|
||||
ang.y mustEqual 1.0546875f
|
||||
ang.z mustEqual 90.35156f
|
||||
vel.isDefined mustEqual true
|
||||
vel.get.x mustEqual 0.0f
|
||||
vel.get.y mustEqual 0.0f
|
||||
|
|
@ -41,7 +41,7 @@ class VehicleStateMessageTest extends Specification {
|
|||
PlanetSideGUID(413),
|
||||
0,
|
||||
Vector3(3674.8438f, 2726.789f, 91.09375f),
|
||||
359.29688f, 1.0546875f, 90.35156f,
|
||||
Vector3(359.29688f, 1.0546875f, 90.35156f),
|
||||
Some(Vector3(0.0f, 0.0f, 0.03125f)),
|
||||
None,
|
||||
0, 0, 15,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
import java.net.{InetAddress, InetSocketAddress}
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware}
|
||||
import net.psforever.packet.{PlanetSideGamePacket, _}
|
||||
import net.psforever.packet.control._
|
||||
|
|
@ -31,8 +29,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
def receive = Initializing
|
||||
|
||||
def Initializing : Receive = {
|
||||
case HelloFriend(sessionId, right) =>
|
||||
this.sessionId = sessionId
|
||||
case HelloFriend(inSessionId, right) =>
|
||||
this.sessionId = inSessionId
|
||||
leftRef = sender()
|
||||
rightRef = right.asInstanceOf[ActorRef]
|
||||
|
||||
|
|
@ -81,7 +79,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
handlePkt(v)
|
||||
}
|
||||
case sync @ ControlSync(diff, unk, f1, f2, f3, f4, fa, fb) =>
|
||||
log.debug(s"SYNC: ${sync}")
|
||||
log.debug(s"SYNC: $sync")
|
||||
val serverTick = Math.abs(System.nanoTime().toInt) // limit the size to prevent encoding error
|
||||
sendResponse(PacketCoding.CreateControlPacket(ControlSyncResp(diff, serverTick,
|
||||
fa, fb, fb, fa)))
|
||||
|
|
@ -113,8 +111,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
val app = CharacterAppearanceData(
|
||||
PlacementData(
|
||||
Vector3(3674.8438f, 2726.789f, 91.15625f),
|
||||
0, 0,
|
||||
19
|
||||
Vector3(0f, 0f, 90f)
|
||||
),
|
||||
BasicCharacterData(
|
||||
"IlllIIIlllIlIllIlllIllI",
|
||||
|
|
@ -166,9 +163,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match {
|
||||
case ConnectToWorldRequestMessage(server, token, majorVersion, minorVersion, revision, buildDate, unk) =>
|
||||
|
||||
val clientVersion = s"Client Version: ${majorVersion}.${minorVersion}.${revision}, ${buildDate}"
|
||||
val clientVersion = s"Client Version: $majorVersion.$minorVersion.$revision, $buildDate"
|
||||
|
||||
log.info(s"New world login to ${server} with Token:${token}. ${clientVersion}")
|
||||
log.info(s"New world login to $server with Token:$token. $clientVersion")
|
||||
|
||||
// ObjectCreateMessage
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, objectHex))
|
||||
|
|
@ -229,6 +226,18 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(PacketCoding.CreateGamePacket(0, CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, ReplicationStreamMessage(5, Some(6), Vector(SquadListing())))) //clear squad list
|
||||
|
||||
val fury = VehicleData(
|
||||
CommonFieldData(
|
||||
PlacementData(3674.8438f, 2732f, 91.15625f, 0.0f, 0.0f, 90.0f),
|
||||
PlanetSideEmpire.VS, 4
|
||||
),
|
||||
255,
|
||||
MountItem(ObjectClass.fury_weapon_systema, PlanetSideGUID(400), 1,
|
||||
WeaponData(0x6, 0x8, 0, ObjectClass.hellfire_ammo, PlanetSideGUID(432), 0, AmmoBoxData(0x8))
|
||||
)
|
||||
)
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, ObjectCreateMessage(ObjectClass.fury, PlanetSideGUID(413), fury)))
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient())
|
||||
|
|
@ -249,13 +258,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case msg @ BeginZoningMessage() =>
|
||||
log.info("Reticulating splines ...")
|
||||
|
||||
case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, is_jumping, unk4, is_cloaking, unk5, unk6) =>
|
||||
case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, yaw, pitch, yawUpper, seq_time, unk3, is_crouching, is_jumping, unk4, is_cloaking, unk5, unk6) =>
|
||||
//log.info("PlayerState: " + msg)
|
||||
|
||||
case msg @ ChildObjectStateMessage(object_guid : PlanetSideGUID, pitch : Int, yaw : Int) =>
|
||||
case msg @ ChildObjectStateMessage(object_guid, pitch, yaw) =>
|
||||
//log.info("ChildObjectState: " + msg)
|
||||
|
||||
case msg @ VehicleStateMessage(vehicle_guid, unk1, pos, roll, pitch, yaw, vel, unk5, unk6, unk7, wheels, unk9, unkA) =>
|
||||
case msg @ VehicleStateMessage(vehicle_guid, unk1, pos, ang, vel, unk5, unk6, unk7, wheels, unk9, unkA) =>
|
||||
//log.info("VehicleState: " + msg)
|
||||
|
||||
case msg @ ProjectileStateMessage(projectile_guid, shot_pos, shot_vector, unk1, unk2, unk3, unk4, time_alive) =>
|
||||
|
|
@ -456,7 +465,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case msg @ TargetingImplantRequest(list) =>
|
||||
log.info("TargetingImplantRequest: "+msg)
|
||||
|
||||
case default => log.error(s"Unhandled GamePacket ${pkt}")
|
||||
case default => log.error(s"Unhandled GamePacket $pkt")
|
||||
}
|
||||
|
||||
def failWithError(error : String) = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue