mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-11 14:34:40 +00:00
removed fire mode override for the Phoenix; added events for loading and manipulation of remote projectiles to AvatarService; ProjectileStateMessage handles projectile data in a simple way; remote projectiles can now be registered and unregistered
This commit is contained in:
parent
fa7365e8af
commit
f1c73688f7
7 changed files with 181 additions and 46 deletions
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import net.psforever.objects.GlobalDefinitions.sparrow_projectile
|
||||
import net.psforever.objects.ballistics.Projectiles
|
||||
import net.psforever.objects.ce.{DeployableCategory, DeployedItem}
|
||||
import net.psforever.objects.definition._
|
||||
|
|
@ -641,8 +640,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)
|
||||
|
|
|
|||
|
|
@ -2,48 +2,56 @@
|
|||
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._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
/**
|
||||
* Dispatched to deliberately render certain projectiles of a weapon on other players' clients.<br>
|
||||
* Dispatched to deliberately control certain projectiles of a weapon on other players' clients.<br>
|
||||
* <br>
|
||||
* This packet is generated by firing specific weapons in specific fire modes.
|
||||
* This packet should be generated by firing specific weapons in specific fire modes.
|
||||
* For example, the Phoenix (`hunterseeker`) discharged in its primary fire mode generates this packet;
|
||||
* but, the Phoenix in secondary fire mode does not.
|
||||
* The Striker (`striker`) discharged in its primary fire mode generates this packet;
|
||||
* but, the Striker in secondary fire mode does not.
|
||||
* The chosen fire mode(s) are not a straight-fire projectile but one that has special control asserted over it.
|
||||
* For the Phoenix, it is user-operated.
|
||||
* For the Striker, it tracks towards a target while the weapon's reticle hovers over that target.<br>
|
||||
* For the Phoenix, it is user operated (camera-guided).
|
||||
* For the Striker, it tracks towards a valid target while the weapon's reticle hovers over that target.<br>
|
||||
* <br>
|
||||
* This packet will continue to be dispatched by the client for as long as the projectile being tracked is in the air.
|
||||
* All projectiles have a maximum lifespan before they will lose control and either despawn and/or explode.
|
||||
* This number is tracked in the packet for simplicity.
|
||||
* If the projectile strikes a valid target, the count will jump to a significantly enormous value beyond its normal lifespan.
|
||||
* This ensures that the projectile - locally and the shared model - will despawn.
|
||||
* @param projectile_guid the projectile
|
||||
* <br>
|
||||
* This control can not be exerted until that projectile is physically constructed on the other clients
|
||||
* in the same way that a player or a vehicle is constructed.
|
||||
* A projectile that exhibits intentional construction behavior is flagged using the property `exists_on_remote_client`.
|
||||
* The model comes with a number of caveats,
|
||||
* some that originate from the object construction process itself,
|
||||
* but also some from this packet.
|
||||
* For example,
|
||||
* as indicated by the static `shot_orient` values reported by this packet.
|
||||
* a discharged controlled projectile will not normally rotate.
|
||||
* A minor loss of lifespan may be levied.
|
||||
* @see `ProjectileDefinition`
|
||||
* @see `TrackedProjectileData`
|
||||
* @param projectile_guid the client-specific local unique identifier of the projectile;
|
||||
* this is __not__ the global unique identifier for the synchronized projectile object
|
||||
* @param shot_pos the position of the projectile
|
||||
* @param shot_vel the velocity of the projectile
|
||||
* @param unk1 na;
|
||||
* usually 0
|
||||
* @param unk2 na;
|
||||
* will remain consistent for the lifespan of a given projectile in most cases
|
||||
* @param unk3 na;
|
||||
* will remain consistent for the lifespan of a given projectile in most cases
|
||||
* @param unk4 na;
|
||||
* usually false
|
||||
* @param shot_orient the orientation of the projectile
|
||||
* @param unk na;
|
||||
* usually `false`
|
||||
* @param time_alive how long the projectile has been in the air;
|
||||
* often expressed in multiples of 2
|
||||
*/
|
||||
final case class ProjectileStateMessage(projectile_guid : PlanetSideGUID,
|
||||
shot_pos : Vector3,
|
||||
shot_vel : Vector3,
|
||||
unk1 : Int,
|
||||
unk2 : Int,
|
||||
unk3 : Int,
|
||||
unk4 : Boolean,
|
||||
shot_orient : Vector3,
|
||||
unk : Boolean,
|
||||
time_alive : Int)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = ProjectileStateMessage
|
||||
|
|
@ -56,10 +64,19 @@ object ProjectileStateMessage extends Marshallable[ProjectileStateMessage] {
|
|||
("projectile_guid" | PlanetSideGUID.codec) ::
|
||||
("shot_pos" | Vector3.codec_pos) ::
|
||||
("shot_vel" | Vector3.codec_float) ::
|
||||
("unk1" | uint8L) ::
|
||||
("unk2" | uint8L) ::
|
||||
("unk3" | uint8L) ::
|
||||
("unk4" | bool) ::
|
||||
("roll" | Angular.codec_roll) ::
|
||||
("pitch" | Angular.codec_pitch) ::
|
||||
("yaw" | Angular.codec_yaw()) ::
|
||||
("unk" | bool) ::
|
||||
("time_alive" | uint16L)
|
||||
).as[ProjectileStateMessage]
|
||||
).xmap[ProjectileStateMessage] (
|
||||
{
|
||||
case guid :: pos :: vel :: roll :: pitch :: yaw :: unk :: time :: HNil =>
|
||||
ProjectileStateMessage(guid, pos, vel, Vector3(roll, pitch, yaw), unk, time)
|
||||
},
|
||||
{
|
||||
case ProjectileStateMessage(guid, pos, vel, Vector3(roll, pitch, yaw), unk, time) =>
|
||||
guid :: pos :: vel :: roll :: pitch :: yaw :: unk :: time :: HNil
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,12 @@ class AvatarService extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.LoadPlayer(pkt))
|
||||
)
|
||||
case AvatarAction.LoadProjectile(player_guid, object_id, obj, cdata) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.LoadPlayer(
|
||||
ObjectCreateMessage(object_id, obj.GUID, cdata)
|
||||
))
|
||||
)
|
||||
case AvatarAction.ObjectDelete(player_guid, item_guid, unk) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ObjectDelete(item_guid, unk))
|
||||
|
|
@ -151,6 +157,10 @@ class AvatarService extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", guid, AvatarResponse.PlayerState(pos, vel, yaw, pitch, yaw_upper, seq_time, is_crouching, is_jumping, jump_thrust, is_cloaking, spectating, weaponInHand))
|
||||
)
|
||||
case AvatarAction.ProjectileState(player_guid, projectile_guid, shot_pos, shot_vel, shot_orient, unk, time_alive) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ProjectileState(projectile_guid, shot_pos, shot_vel, shot_orient, unk, time_alive))
|
||||
)
|
||||
case AvatarAction.PickupItem(player_guid, zone, target, slot, item, unk) =>
|
||||
janitor forward RemoverActor.ClearSpecific(List(item), zone)
|
||||
AvatarEvents.publish(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.avatar
|
||||
|
||||
<<<<<<< fa7365e8af5d0b21c3934ed745895edd46f741a6:common/src/main/scala/services/avatar/AvatarServiceMessage.scala
|
||||
import net.psforever.objects.{PlanetSideGameObject, Player}
|
||||
import net.psforever.objects.ballistics.SourceEntry
|
||||
=======
|
||||
import net.psforever.objects.ballistics.{Projectile, SourceEntry}
|
||||
>>>>>>> removed fire mode override for the Phoenix; added events for loading and manipulation of remote projectiles to AvatarService; ProjectileStateMessage handles projectile data in a simple way; remote projectiles can now be registered and unregistered:common/src/main/scala/services/avatar/AvatarAction.scala
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.Container
|
||||
|
|
@ -30,7 +34,7 @@ object AvatarAction {
|
|||
final case class ChangeFireState_Start(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class ChangeFireState_Stop(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Action
|
||||
final case class EnvironmentalDamage(player_guid : PlanetSideGUID, amont: Int) extends Action
|
||||
final case class EnvironmentalDamage(player_guid : PlanetSideGUID, amount: Int) extends Action
|
||||
final case class Damage(player_guid : PlanetSideGUID, target : Player, resolution_function : Any=>Unit) extends Action
|
||||
final case class DeployItem(player_guid : PlanetSideGUID, item : PlanetSideGameObject with Deployable) extends Action
|
||||
final case class Destroy(victim : PlanetSideGUID, killer : PlanetSideGUID, weapon : PlanetSideGUID, pos : Vector3) extends Action
|
||||
|
|
@ -40,6 +44,7 @@ object AvatarAction {
|
|||
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
|
||||
final case class LoadProjectile(player_guid : PlanetSideGUID, object_id : Int, obj : Projectile, cdata : ConstructorData) extends Action
|
||||
final case class ObjectDelete(player_guid : PlanetSideGUID, item_guid : PlanetSideGUID, unk : Int = 0) extends Action
|
||||
final case class ObjectHeld(player_guid : PlanetSideGUID, slot : Int) extends Action
|
||||
final case class PlanetsideAttribute(player_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Action
|
||||
|
|
@ -47,6 +52,7 @@ object AvatarAction {
|
|||
final case class PlanetsideAttributeSelf(player_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Action
|
||||
final case class PlayerState(player_guid : PlanetSideGUID, pos : Vector3, vel : Option[Vector3], facingYaw : Float, facingPitch : Float, facingYawUpper : Float, timestamp : Int, is_crouching : Boolean, is_jumping : Boolean, jump_thrust : Boolean, is_cloaked : Boolean, spectator : Boolean, weaponInHand : Boolean) extends Action
|
||||
final case class PickupItem(player_guid : PlanetSideGUID, zone : Zone, target : PlanetSideGameObject with Container, slot : Int, item : Equipment, unk : Int = 0) extends Action
|
||||
final case class ProjectileState(player_guid : PlanetSideGUID, projectile_guid : PlanetSideGUID, shot_pos : Vector3, shot_vel : Vector3, shot_orient : Vector3, unk : Boolean, time_alive : Int) extends Action
|
||||
final case class PutDownFDU(player_guid : PlanetSideGUID) extends Action
|
||||
final case class Release(player : Player, zone : Zone, time : Option[FiniteDuration] = None) extends Action
|
||||
final case class Revive(target_guid: PlanetSideGUID) extends Action
|
||||
|
|
|
|||
|
|
@ -33,12 +33,18 @@ object AvatarResponse {
|
|||
final case class HitHint(source_guid : PlanetSideGUID) extends Response
|
||||
final case class KilledWhileInVehicle() extends Response
|
||||
final case class LoadPlayer(pkt : ObjectCreateMessage) extends Response
|
||||
final case class LoadProjectile(pkt : ObjectCreateMessage) extends Response
|
||||
final case class ObjectDelete(item_guid : PlanetSideGUID, unk : Int) extends Response
|
||||
final case class ObjectHeld(slot : Int) extends Response
|
||||
final case class PlanetsideAttribute(attribute_type : Int, attribute_value : Long) extends Response
|
||||
<<<<<<< fa7365e8af5d0b21c3934ed745895edd46f741a6:common/src/main/scala/services/avatar/AvatarServiceResponse.scala
|
||||
final case class PlanetsideAttributeToAll(attribute_type : Int, attribute_value : Long) extends Response
|
||||
final case class PlanetsideAttributeSelf(attribute_type : Int, attribute_value : Long) extends Response
|
||||
final case class PlayerState(pos : Vector3, vel : Option[Vector3], facingYaw : Float, facingPitch : Float, facingYawUpper : Float, timestamp : Int, is_crouching : Boolean, is_jumping : Boolean, jump_thrust : Boolean, is_cloaked : Boolean, spectator : Boolean, weaponInHand : Boolean) extends Response
|
||||
=======
|
||||
final case class PlayerState(msg : PlayerStateMessageUpstream, spectator : Boolean, weaponInHand : Boolean) extends Response
|
||||
final case class ProjectileState(projectile_guid : PlanetSideGUID, shot_pos : Vector3, shot_vel : Vector3, shot_orient : Vector3, unk : Boolean, time_alive : Int) extends Response
|
||||
>>>>>>> removed fire mode override for the Phoenix; added events for loading and manipulation of remote projectiles to AvatarService; ProjectileStateMessage handles projectile data in a simple way; remote projectiles can now be registered and unregistered:common/src/main/scala/services/avatar/AvatarResponse.scala
|
||||
final case class PutDownFDU(target_guid : PlanetSideGUID) extends Response
|
||||
final case class Release(player : Player) extends Response
|
||||
final case class Reload(weapon_guid : PlanetSideGUID) extends Response
|
||||
|
|
|
|||
|
|
@ -12,18 +12,12 @@ class ProjectileStateMessageTest extends Specification {
|
|||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case ProjectileStateMessage(projectile, pos, vel, unk1, unk2, unk3, unk4, time_alive) =>
|
||||
case ProjectileStateMessage(projectile, pos, vel, orient, unk, time_alive) =>
|
||||
projectile mustEqual PlanetSideGUID(40229)
|
||||
pos.x mustEqual 4611.539f
|
||||
pos.y mustEqual 5576.375f
|
||||
pos.z mustEqual 82.328125f
|
||||
vel.x mustEqual 18.64686f
|
||||
vel.y mustEqual -33.43247f
|
||||
vel.z mustEqual 11.599553f
|
||||
unk1 mustEqual 0
|
||||
unk2 mustEqual 248
|
||||
unk3 mustEqual 236
|
||||
unk4 mustEqual false
|
||||
pos mustEqual Vector3(4611.539f, 5576.375f, 82.328125f)
|
||||
vel mustEqual Vector3(18.64686f, -33.43247f, 11.599553f)
|
||||
orient mustEqual Vector3(0, 22.5f, 56.25f)
|
||||
unk mustEqual false
|
||||
time_alive mustEqual 4
|
||||
case _ =>
|
||||
ko
|
||||
|
|
@ -35,10 +29,17 @@ class ProjectileStateMessageTest extends Specification {
|
|||
PlanetSideGUID(40229),
|
||||
Vector3(4611.539f, 5576.375f, 82.328125f),
|
||||
Vector3(18.64686f, -33.43247f, 11.599553f),
|
||||
0, 248, 236, false, 4
|
||||
Vector3(0, 22.5f, 56.25f),
|
||||
false,
|
||||
4
|
||||
)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
//pkt mustEqual string
|
||||
val pkt_bits = pkt.toBitVector
|
||||
val str_bits = string.toBitVector
|
||||
pkt_bits.take(184) mustEqual str_bits.take(184) //skip 1 bit
|
||||
pkt_bits.drop(185).take(7) mustEqual str_bits.drop(185).take(7) //skip 1 bit
|
||||
pkt_bits.drop(193) mustEqual str_bits.drop(193)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue