mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-02-12 19:31:04 +00:00
events for future expansion; added custom projectile remote client data for OCM packet creation; initial projectile velocity calculation; (too many) details when it comes to Enumerations for projectiles; hooked up theoretical projectile creatiuon, management, and deletion
This commit is contained in:
parent
f1c73688f7
commit
8952ab86f6
10 changed files with 258 additions and 65 deletions
|
|
@ -630,9 +630,7 @@ object GlobalDefinitions {
|
|||
|
||||
val maelstrom = ToolDefinition(ObjectClass.maelstrom)
|
||||
|
||||
val phoenix = new ToolDefinition(ObjectClass.phoenix) {
|
||||
override def NextFireModeIndex(index : Int) : Int = index
|
||||
} //decimator
|
||||
val phoenix = ToolDefinition(ObjectClass.phoenix) //decimator
|
||||
|
||||
val striker = new ToolDefinition(ObjectClass.striker) {
|
||||
override def NextFireModeIndex(index : Int) : Int = index
|
||||
|
|
@ -640,8 +638,8 @@ object GlobalDefinitions {
|
|||
}
|
||||
|
||||
val hunterseeker = new ToolDefinition(ObjectClass.hunterseeker) {
|
||||
// override def NextFireModeIndex(index : Int) : Int = index
|
||||
// DefaultFireModeIndex = 1
|
||||
override def NextFireModeIndex(index : Int) : Int = index
|
||||
DefaultFireModeIndex = 1
|
||||
} //phoenix
|
||||
|
||||
val lancer = ToolDefinition(ObjectClass.lancer)
|
||||
|
|
@ -2221,6 +2219,7 @@ object GlobalDefinitions {
|
|||
aphelion_starfire_projectile.Lifespan = 7f
|
||||
aphelion_starfire_projectile.ProjectileDamageType = DamageType.Aggravated
|
||||
aphelion_starfire_projectile.ExistsOnRemoteClients = true
|
||||
aphelion_starfire_projectile.RemoteClientData = (39577, 249) //starfire_projectile data
|
||||
aphelion_starfire_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(aphelion_starfire_projectile)
|
||||
|
||||
|
|
@ -2699,6 +2698,7 @@ object GlobalDefinitions {
|
|||
hunter_seeker_missile_projectile.InitialVelocity = 40
|
||||
hunter_seeker_missile_projectile.Lifespan = 6.3f
|
||||
hunter_seeker_missile_projectile.ExistsOnRemoteClients = true
|
||||
hunter_seeker_missile_projectile.RemoteClientData = (39577, 201)
|
||||
hunter_seeker_missile_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(hunter_seeker_missile_projectile)
|
||||
|
||||
|
|
@ -2986,6 +2986,7 @@ object GlobalDefinitions {
|
|||
oicw_projectile.InitialVelocity = 5
|
||||
oicw_projectile.Lifespan = 6.1f
|
||||
oicw_projectile.ExistsOnRemoteClients = true
|
||||
oicw_projectile.RemoteClientData = (13107, 195)
|
||||
oicw_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(oicw_projectile)
|
||||
|
||||
|
|
@ -2997,7 +2998,7 @@ object GlobalDefinitions {
|
|||
oicw_little_buddy.ProjectileDamageType = DamageType.Splash
|
||||
oicw_little_buddy.InitialVelocity = 40
|
||||
oicw_little_buddy.Lifespan = 0.5f
|
||||
oicw_little_buddy.ExistsOnRemoteClients = true
|
||||
oicw_little_buddy.ExistsOnRemoteClients = false //TODO true
|
||||
oicw_little_buddy.Packet = projectileConverter
|
||||
//add_property oicw_little_buddy multi_stage_spawn_server_side true ...
|
||||
ProjectileDefinition.CalculateDerivedFields(oicw_little_buddy)
|
||||
|
|
@ -3080,6 +3081,7 @@ object GlobalDefinitions {
|
|||
peregrine_sparrow_projectile.InitialVelocity = 45
|
||||
peregrine_sparrow_projectile.Lifespan = 7.5f
|
||||
peregrine_sparrow_projectile.ExistsOnRemoteClients = true
|
||||
peregrine_sparrow_projectile.RemoteClientData = (13107, 187) //sparrow_projectile data
|
||||
peregrine_sparrow_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(peregrine_sparrow_projectile)
|
||||
|
||||
|
|
@ -3133,6 +3135,7 @@ object GlobalDefinitions {
|
|||
phoenix_missile_guided_projectile.InitialVelocity = 0
|
||||
phoenix_missile_guided_projectile.Lifespan = 3f
|
||||
phoenix_missile_guided_projectile.ExistsOnRemoteClients = true
|
||||
phoenix_missile_guided_projectile.RemoteClientData = (39577, 201) //hunter_seeker_missile_projectile data
|
||||
phoenix_missile_guided_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(phoenix_missile_guided_projectile)
|
||||
|
||||
|
|
@ -3411,6 +3414,7 @@ object GlobalDefinitions {
|
|||
sparrow_projectile.InitialVelocity = 60
|
||||
sparrow_projectile.Lifespan = 5.85f
|
||||
sparrow_projectile.ExistsOnRemoteClients = true
|
||||
sparrow_projectile.RemoteClientData = (13107, 187)
|
||||
sparrow_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(sparrow_projectile)
|
||||
|
||||
|
|
@ -3427,6 +3431,7 @@ object GlobalDefinitions {
|
|||
sparrow_secondary_projectile.InitialVelocity = 60
|
||||
sparrow_secondary_projectile.Lifespan = 5.85f
|
||||
sparrow_secondary_projectile.ExistsOnRemoteClients = true
|
||||
sparrow_secondary_projectile.RemoteClientData = (13107, 187)
|
||||
sparrow_secondary_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(sparrow_secondary_projectile)
|
||||
|
||||
|
|
@ -3479,6 +3484,7 @@ object GlobalDefinitions {
|
|||
starfire_projectile.InitialVelocity = 45
|
||||
starfire_projectile.Lifespan = 7.8f
|
||||
starfire_projectile.ExistsOnRemoteClients = true
|
||||
starfire_projectile.RemoteClientData = (39577, 249)
|
||||
starfire_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(starfire_projectile)
|
||||
|
||||
|
|
@ -3512,6 +3518,7 @@ object GlobalDefinitions {
|
|||
striker_missile_targeting_projectile.InitialVelocity = 30
|
||||
striker_missile_targeting_projectile.Lifespan = 4.2f
|
||||
striker_missile_targeting_projectile.ExistsOnRemoteClients = true
|
||||
striker_missile_targeting_projectile.RemoteClientData = (26214, 134)
|
||||
striker_missile_targeting_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(striker_missile_targeting_projectile)
|
||||
|
||||
|
|
@ -3601,6 +3608,7 @@ object GlobalDefinitions {
|
|||
wasp_rocket_projectile.InitialVelocity = 60
|
||||
wasp_rocket_projectile.Lifespan = 6.5f
|
||||
wasp_rocket_projectile.ExistsOnRemoteClients = true
|
||||
wasp_rocket_projectile.RemoteClientData = (0, 208)
|
||||
wasp_rocket_projectile.Packet = projectileConverter
|
||||
ProjectileDefinition.CalculateDerivedFields(wasp_rocket_projectile)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,15 @@ final case class Projectile(profile : ProjectileDefinition,
|
|||
shot_origin : Vector3,
|
||||
shot_angle : Vector3,
|
||||
fire_time: Long = System.nanoTime) extends PlanetSideGameObject {
|
||||
Position = shot_origin
|
||||
Orientation = shot_angle
|
||||
Velocity = {
|
||||
val initVel : Int = profile.InitialVelocity //initial velocity
|
||||
val radAngle : Double = math.toRadians(shot_angle.y) //angle of elevation
|
||||
val rise : Float = initVel * math.sin(radAngle).toFloat //z
|
||||
val ground : Float = initVel * math.cos(radAngle).toFloat //base
|
||||
Vector3.Rz(Vector3(0, -ground, 0), shot_angle.z) + Vector3.z(rise)
|
||||
}
|
||||
/** Information about the current world coordinates and orientation of the projectile */
|
||||
val current : SimpleWorldEntity = new SimpleWorldEntity()
|
||||
private var resolved : ProjectileResolution.Value = ProjectileResolution.Unresolved
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class ProjectileDefinition(objectId : Int) extends ObjectDefinition(objectId)
|
|||
private var damageRadius : Float = 1f
|
||||
private var useDamage1Subtract : Boolean = false
|
||||
private var existsOnRemoteClients : Boolean = false //`true` spawns a server-managed object
|
||||
private var remoteClientData : (Int, Int) = (0, 0) //artificial values; for ObjectCreateMessage packet (oicw_little_buddy is undefined)
|
||||
//derived calculations
|
||||
private var distanceMax : Float = 0f
|
||||
private var distanceFromAcceleration : Float = 0f
|
||||
|
|
@ -117,6 +118,13 @@ class ProjectileDefinition(objectId : Int) extends ObjectDefinition(objectId)
|
|||
ExistsOnRemoteClients
|
||||
}
|
||||
|
||||
def RemoteClientData : (Int, Int) = remoteClientData
|
||||
|
||||
def RemoteClientData_=(remoteClientData : (Int, Int)) : (Int, Int) = {
|
||||
this.remoteClientData = remoteClientData
|
||||
RemoteClientData
|
||||
}
|
||||
|
||||
def DistanceMax : Float = distanceMax //accessor only
|
||||
|
||||
def DistanceFromAcceleration : Float = distanceFromAcceleration //accessor only
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class ProjectileConverter extends ObjectCreateConverter[Projectile]() {
|
|||
PlacementData(
|
||||
obj.Position,
|
||||
obj.Orientation,
|
||||
obj.Velocity
|
||||
None
|
||||
),
|
||||
CommonFieldData(
|
||||
obj.owner.Faction,
|
||||
|
|
@ -29,11 +29,11 @@ class ProjectileConverter extends ObjectCreateConverter[Projectile]() {
|
|||
PlanetSideGUID(0)
|
||||
)
|
||||
),
|
||||
obj.profile.RemoteClientData._1,
|
||||
obj.profile.RemoteClientData._2,
|
||||
FlightPhysics.State4,
|
||||
0,
|
||||
0,
|
||||
FlightPhysics.State3,
|
||||
7,
|
||||
2
|
||||
0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,56 @@
|
|||
package net.psforever.packet.game.objectcreate
|
||||
|
||||
import net.psforever.packet.{Marshallable, PacketHelpers}
|
||||
import scodec.{Attempt, Codec, Err}
|
||||
import scodec.{Attempt, Codec}
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
object TrackedProjectile extends Enumeration {
|
||||
type Type = Value
|
||||
|
||||
val OICWLittleBuddy = Value(-1) //?, ?
|
||||
val Meteor = Value(32) //0, 32
|
||||
val Wasp = Value(208) //0, 208
|
||||
val Sparrow = Value(3355579) //13107, 187
|
||||
val OICW = Value(3355587) //13107, 195
|
||||
val Striker = Value(6710918) //26214, 134
|
||||
val HunterSeeker = Value(10131913) //39577, 201
|
||||
val Starfire = Value(10131961) //39577, 249
|
||||
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint24)
|
||||
}
|
||||
|
||||
object TrackedProjectiles {
|
||||
abstract class Data(val is : TrackedProjectile.Value, val a : Int, val b : Int)
|
||||
|
||||
final case object Meteor extends Data(TrackedProjectile.Meteor, 0, 32)
|
||||
final case object Wasp extends Data(TrackedProjectile.Wasp, 0, 208)
|
||||
final case object Sparrow extends Data(TrackedProjectile.Sparrow, 13107, 187)
|
||||
final case object OICW extends Data(TrackedProjectile.OICW, 13107, 195)
|
||||
final case object Striker extends Data(TrackedProjectile.Striker, 26214, 134)
|
||||
final case object HunterSeeker extends Data(TrackedProjectile.HunterSeeker, 39577, 201)
|
||||
final case object Starfire extends Data(TrackedProjectile.Starfire, 39577, 249)
|
||||
class OICWLittleBuddy(x : Int, y : Int) extends Data(TrackedProjectile.OICWLittleBuddy, x, y)
|
||||
|
||||
val values: Seq[TrackedProjectiles.Data] = Seq(Meteor, Wasp, Sparrow, OICW, Striker, HunterSeeker, Starfire)
|
||||
|
||||
def apply(x : Int, y : Int) : TrackedProjectiles.Data = {
|
||||
values.find(p => p.a == x && p.b == y) match {
|
||||
case Some(projectileData) => projectileData
|
||||
case None =>
|
||||
throw new IllegalArgumentException("no combination of projectile data equates to a defined projectile type")
|
||||
}
|
||||
}
|
||||
|
||||
def apply(is : TrackedProjectile.Value) : TrackedProjectiles.Data = {
|
||||
values.find(p => p.is == is) match {
|
||||
case Some(projectileData) => projectileData
|
||||
case None =>
|
||||
throw new IllegalArgumentException("unknown projectile type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object FlightPhysics extends Enumeration {
|
||||
type Type = Value
|
||||
|
||||
|
|
@ -27,41 +73,38 @@ object FlightPhysics extends Enumeration {
|
|||
|
||||
/**
|
||||
* A representation of a projectile that the server must intentionally convey to players other than the shooter.
|
||||
* @param data common game object information
|
||||
* @param unk2 na
|
||||
* @param unit_distance_limit how quickly the projectile travels before naturally being destroyed
|
||||
* `FlightPhysics` needs to be
|
||||
* @param common_data common game object information
|
||||
* @param unk3 na
|
||||
*/
|
||||
final case class TrackedProjectileData(data : CommonFieldDataWithPlacement,
|
||||
unk2 : Int,
|
||||
unit_distance_limit : Int,
|
||||
final case class TrackedProjectileData(common_data : CommonFieldDataWithPlacement,
|
||||
u1 : Int,
|
||||
u2 : Int,
|
||||
unk3 : FlightPhysics.Value,
|
||||
unk4 : Int,
|
||||
unk5 : Int
|
||||
) extends ConstructorData {
|
||||
override def bitsize : Long = 33L + data.bitsize
|
||||
override def bitsize : Long = 33L + common_data.bitsize
|
||||
}
|
||||
|
||||
object TrackedProjectileData extends Marshallable[TrackedProjectileData] {
|
||||
implicit val codec : Codec[TrackedProjectileData] = (
|
||||
("data" | CommonFieldDataWithPlacement.codec) ::
|
||||
("unk2" | uint16) ::
|
||||
("unit_distance_limit" | uint8) ::
|
||||
("u1" | uint16) ::
|
||||
("u2" | uint8) ::
|
||||
("unk3" | FlightPhysics.codec) ::
|
||||
("unk4" | uint(3)) ::
|
||||
("unk5" | uint2)
|
||||
).exmap[TrackedProjectileData] (
|
||||
{
|
||||
case data :: unk2 :: lim :: unk3 :: unk4 :: unk5 :: HNil =>
|
||||
Attempt.successful(TrackedProjectileData(data, unk2, lim, unk3, unk4, unk5))
|
||||
case data :: u1 :: u2 :: unk3 :: unk4 :: unk5 :: HNil =>
|
||||
Attempt.successful(TrackedProjectileData(data, u1, u2, unk3, unk4, unk5))
|
||||
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid projectile data format - $data"))
|
||||
// case data =>
|
||||
// Attempt.failure(Err(s"invalid projectile data format - $data"))
|
||||
},
|
||||
{
|
||||
case TrackedProjectileData(data, unk2, lim, unk3, unk4, unk5) =>
|
||||
Attempt.successful(data :: unk2 :: lim :: unk3 :: unk4 :: unk5 :: HNil)
|
||||
case TrackedProjectileData(data, u1, u2, unk3, unk4, unk5) =>
|
||||
Attempt.successful(data :: u1 :: u2 :: unk3 :: unk4 :: unk5 :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,10 @@ class AvatarService extends Actor {
|
|||
AvatarResponse.EquipmentInHand(ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData))
|
||||
)
|
||||
)
|
||||
case AvatarAction.GenericObjectAction(player_guid, object_guid, action_code) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.GenericObjectAction(object_guid, action_code))
|
||||
)
|
||||
case AvatarAction.HitHint(source_guid, player_guid) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.HitHint(source_guid))
|
||||
|
|
@ -129,7 +133,7 @@ class AvatarService extends Actor {
|
|||
)
|
||||
case AvatarAction.LoadProjectile(player_guid, object_id, obj, cdata) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.LoadPlayer(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.LoadProjectile(
|
||||
ObjectCreateMessage(object_id, obj.GUID, cdata)
|
||||
))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ object AvatarAction {
|
|||
final case class DestroyDisplay(killer : SourceEntry, victim : SourceEntry, method : Int, unk : Int = 121) extends Action
|
||||
final case class DropItem(player_guid : PlanetSideGUID, item : Equipment, zone : Zone) extends Action
|
||||
final case class EquipmentInHand(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
|
||||
final case class GenericObjectAction(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, action_code : Int) extends Action
|
||||
final case class HitHint(source_guid : PlanetSideGUID, player_guid : PlanetSideGUID) extends Action
|
||||
final case class KilledWhileInVehicle(player_guid : PlanetSideGUID) extends Action
|
||||
final case class LoadPlayer(player_guid : PlanetSideGUID, object_id : Int, target_guid : PlanetSideGUID, cdata : ConstructorData, pdata : Option[ObjectCreateMessageParent]) extends Action
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ object AvatarResponse {
|
|||
final case class DestroyDisplay(killer : SourceEntry, victim : SourceEntry, method : Int, unk : Int) extends Response
|
||||
final case class DropItem(pkt : ObjectCreateMessage) extends Response
|
||||
final case class EquipmentInHand(pkt : ObjectCreateMessage) extends Response
|
||||
final case class GenericObjectAction(object_guid : PlanetSideGUID, action_code : Int) extends Response
|
||||
final case class HitHint(source_guid : PlanetSideGUID) extends Response
|
||||
final case class KilledWhileInVehicle() extends Response
|
||||
final case class LoadPlayer(pkt : ObjectCreateMessage) extends Response
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ import scodec.bits._
|
|||
|
||||
class TrackedProjectileDataTest extends Specification {
|
||||
val string_striker_projectile = hex"17 C5000000 A4B 009D 4C129 0CB0A 9814 00 F5 E3 040000666686400"
|
||||
val string_hunter_seeker_missile_projectile = hex"17 c5000000 ca9 ab9e af127 ec465 3723 00 15 c4 2400009a99c9400"
|
||||
|
||||
"TrackedProjectileData" should {
|
||||
"decode" in {
|
||||
"decode (striker_missile_targeting_projectile)" in {
|
||||
PacketCoding.DecodePacket(string_striker_projectile).require match {
|
||||
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
||||
len mustEqual 197
|
||||
|
|
@ -46,7 +47,41 @@ class TrackedProjectileDataTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
"decode (hunter_seeker_missile_projectile)" in {
|
||||
PacketCoding.DecodePacket(string_hunter_seeker_missile_projectile).require match {
|
||||
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
||||
len mustEqual 197
|
||||
cls mustEqual ObjectClass.hunter_seeker_missile_projectile
|
||||
guid mustEqual PlanetSideGUID(40619)
|
||||
parent.isDefined mustEqual false
|
||||
data match {
|
||||
case TrackedProjectileData(CommonFieldDataWithPlacement(pos, deploy), unk2, lim, unk3, unk4, unk5) =>
|
||||
pos.coord mustEqual Vector3(3621.3672f, 2701.8438f, 140.85938f)
|
||||
pos.orient mustEqual Vector3(0, 300.9375f, 258.75f)
|
||||
deploy.faction mustEqual PlanetSideEmpire.NC
|
||||
deploy.bops mustEqual false
|
||||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.v4.isEmpty mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(0)
|
||||
|
||||
unk2 mustEqual 39577
|
||||
lim mustEqual 201
|
||||
unk3 mustEqual FlightPhysics.State4
|
||||
unk4 mustEqual 0
|
||||
unk5 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (striker_missile_targeting_projectile)" in {
|
||||
val obj = TrackedProjectileData(
|
||||
CommonFieldDataWithPlacement(
|
||||
PlacementData(4644.5938f, 5472.0938f, 82.375f, 0f, 30.9375f, 171.5625f),
|
||||
|
|
@ -63,4 +98,21 @@ class TrackedProjectileDataTest extends Specification {
|
|||
pkt.toBitVector.drop(141) mustEqual string_striker_projectile.toBitVector.drop(141)
|
||||
}
|
||||
}
|
||||
|
||||
"encode (hunter_seeker_missile_projectile)" in {
|
||||
val obj = TrackedProjectileData(
|
||||
CommonFieldDataWithPlacement(
|
||||
PlacementData(3621.3672f, 2701.8438f, 140.85938f, 0, 300.9375f, 258.75f),
|
||||
CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
|
||||
),
|
||||
39577, 201, FlightPhysics.State4, 0, 0
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.hunter_seeker_missile_projectile, PlanetSideGUID(40619), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
//pkt mustEqual string_hunter_seeker_missile_projectile
|
||||
|
||||
pkt.toBitVector.take(132) mustEqual string_hunter_seeker_missile_projectile.toBitVector.take(132)
|
||||
pkt.toBitVector.drop(133).take(7) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(133).take(7)
|
||||
pkt.toBitVector.drop(141) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(141)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue