mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-02 19:50:21 +00:00
commit
599d767598
22 changed files with 810 additions and 91 deletions
|
|
@ -25,6 +25,7 @@ ignore:
|
|||
- "common/src/main/scala/net/psforever/types/Angular.scala"
|
||||
- "common/src/main/scala/net/psforever/types/CertificationType.scala"
|
||||
- "common/src/main/scala/net/psforever/types/ChatMessageType.scala"
|
||||
- "common/src/main/scala/net/psforever/types/DriveState.scala"
|
||||
- "common/src/main/scala/net/psforever/types/EmoteType.scala"
|
||||
- "common/src/main/scala/net/psforever/types/ExoSuitType.scala"
|
||||
- "common/src/main/scala/net/psforever/types/GrenadeState.scala"
|
||||
|
|
|
|||
|
|
@ -2349,6 +2349,9 @@ object GlobalDefinitions {
|
|||
ams.MountPoints += 2 -> 0
|
||||
ams.Utilities += 3 -> UtilityType.order_terminala
|
||||
ams.Utilities += 4 -> UtilityType.order_terminalb
|
||||
ams.Deployment = true
|
||||
ams.DeployTime = 2000
|
||||
ams.UndeployTime = 2000
|
||||
ams.Packet = utilityConverter
|
||||
|
||||
val variantConverter = new VariantVehicleConverter
|
||||
|
|
@ -2356,6 +2359,9 @@ object GlobalDefinitions {
|
|||
router.MountPoints += 1 -> 0
|
||||
router.TrunkSize = InventoryTile.Tile1511
|
||||
router.TrunkOffset = 30
|
||||
router.Deployment = true
|
||||
router.DeployTime = 2000
|
||||
router.UndeployTime = 2000
|
||||
router.Packet = variantConverter
|
||||
|
||||
switchblade.Seats += 0 -> new SeatDefinition()
|
||||
|
|
@ -2365,6 +2371,9 @@ object GlobalDefinitions {
|
|||
switchblade.MountPoints += 2 -> 0
|
||||
switchblade.TrunkSize = InventoryTile.Tile1511
|
||||
switchblade.TrunkOffset = 30
|
||||
switchblade.Deployment = true
|
||||
switchblade.DeployTime = 2000
|
||||
switchblade.UndeployTime = 2000
|
||||
switchblade.Packet = variantConverter
|
||||
|
||||
flail.Seats += 0 -> new SeatDefinition()
|
||||
|
|
@ -2373,6 +2382,9 @@ object GlobalDefinitions {
|
|||
flail.MountPoints += 1 -> 0
|
||||
flail.TrunkSize = InventoryTile.Tile1511
|
||||
flail.TrunkOffset = 30
|
||||
flail.Deployment = true
|
||||
flail.DeployTime = 2000
|
||||
flail.UndeployTime = 2000
|
||||
flail.Packet = variantConverter
|
||||
|
||||
mosquito.Seats += 0 -> new SeatDefinition()
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem,
|
|||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.deploy.Deployment
|
||||
import net.psforever.objects.vehicles.{AccessPermissionGroup, Seat, Utility, VehicleLockState}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.DriveState
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -20,8 +20,7 @@ import scala.annotation.tailrec
|
|||
* All infantry seating, all mounted weapons, and the trunk space are considered part of the same index hierarchy.
|
||||
* Generally, all seating is declared first - the driver and passengers and and gunners.
|
||||
* Following that are the mounted weapons and other utilities.
|
||||
* Trunk space starts being indexed afterwards.<br>
|
||||
* <br>
|
||||
* Trunk space starts being indexed afterwards.
|
||||
* To keep it simple, infantry seating, mounted weapons, and utilities are stored separately.<br>
|
||||
* <br>
|
||||
* Vehicles maintain a `Map` of `Utility` objects in given index positions.
|
||||
|
|
@ -38,12 +37,12 @@ import scala.annotation.tailrec
|
|||
class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServerObject
|
||||
with FactionAffinity
|
||||
with Mountable
|
||||
with Deployment
|
||||
with Container {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.TR
|
||||
private var owner : Option[PlanetSideGUID] = None
|
||||
private var health : Int = 1
|
||||
private var shields : Int = 0
|
||||
private var deployed : DriveState.Value = DriveState.Mobile
|
||||
private var decal : Int = 0
|
||||
private var trunkAccess : Option[PlanetSideGUID] = None
|
||||
private var jammered : Boolean = false
|
||||
|
|
@ -125,17 +124,6 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
Definition.MaxShields
|
||||
}
|
||||
|
||||
def Drive : DriveState.Value = {
|
||||
this.deployed
|
||||
}
|
||||
|
||||
def Drive_=(deploy : DriveState.Value) : DriveState.Value = {
|
||||
if(Definition.Deployment) {
|
||||
this.deployed = deploy
|
||||
}
|
||||
Drive
|
||||
}
|
||||
|
||||
def Decal : Int = {
|
||||
this.decal
|
||||
}
|
||||
|
|
@ -353,6 +341,10 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
}
|
||||
}
|
||||
|
||||
override def DeployTime = Definition.DeployTime
|
||||
|
||||
override def UndeployTime = Definition.UndeployTime
|
||||
|
||||
def Inventory : GridInventory = trunk
|
||||
|
||||
def Find(obj : Equipment) : Option[Int] = Find(obj.GUID)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
|
|||
private val weapons : mutable.HashMap[Int, ToolDefinition] = mutable.HashMap[Int, ToolDefinition]()
|
||||
private var deployment : Boolean = false
|
||||
private val utilities : mutable.HashMap[Int, UtilityType.Value] = mutable.HashMap()
|
||||
private var deploymentTime_Deploy : Int = 0 //ms
|
||||
private var deploymentTime_Undeploy : Int = 0 //ms
|
||||
private var trunkSize : InventoryTile = InventoryTile.None
|
||||
private var trunkOffset : Int = 0
|
||||
private var canCloak : Boolean = false
|
||||
|
|
@ -70,8 +72,23 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
|
|||
Deployment
|
||||
}
|
||||
|
||||
|
||||
def Utilities : mutable.HashMap[Int, UtilityType.Value] = utilities
|
||||
|
||||
def DeployTime : Int = deploymentTime_Deploy
|
||||
|
||||
def DeployTime_=(dtime : Int) : Int = {
|
||||
deploymentTime_Deploy = dtime
|
||||
DeployTime
|
||||
}
|
||||
|
||||
def UndeployTime : Int = deploymentTime_Undeploy
|
||||
|
||||
def UndeployTime_=(dtime : Int) : Int = {
|
||||
deploymentTime_Undeploy = dtime
|
||||
UndeployTime
|
||||
}
|
||||
|
||||
def TrunkSize : InventoryTile = trunkSize
|
||||
|
||||
def TrunkSize_=(tile : InventoryTile) : InventoryTile = {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
|
|||
0,
|
||||
obj.Health / obj.MaxHealth * 255, //TODO not precise
|
||||
false, false,
|
||||
obj.Drive,
|
||||
obj.DeploymentState,
|
||||
false,
|
||||
false,
|
||||
obj.Cloaked,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.deploy
|
||||
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.types.DriveState
|
||||
|
||||
/**
|
||||
* A `trait` for the purposes of deploying a server object that supports the operation.
|
||||
* As a mixin, it provides the local variable used to keep track of the deployment state
|
||||
* and the logic to change the value of the deployment.
|
||||
* Initially, the deployment state is `Mobile`.
|
||||
*/
|
||||
trait Deployment {
|
||||
this : PlanetSideServerObject =>
|
||||
|
||||
private var deployState : DriveState.Value = DriveState.Mobile
|
||||
|
||||
def DeployTime : Int = 0 //ms
|
||||
|
||||
def UndeployTime : Int = 0 //ms
|
||||
|
||||
def DeploymentState : DriveState.Value = deployState
|
||||
|
||||
def DeploymentState_=(to_deploy_state : DriveState.Value) : DriveState.Value = {
|
||||
deployState = to_deploy_state
|
||||
DeploymentState
|
||||
}
|
||||
}
|
||||
|
||||
object Deployment {
|
||||
/**
|
||||
* A shorthand `type` for a valid object of `Deployment`.
|
||||
*/
|
||||
type DeploymentObject = PlanetSideServerObject with Deployment
|
||||
|
||||
/**
|
||||
* A message for instigating a change in deployment state.
|
||||
* @param state the new deployment state
|
||||
*/
|
||||
final case class TryDeploymentChange(state : DriveState.Value)
|
||||
/**
|
||||
* A message for instigating a change to a deploy state.
|
||||
* @param state the new deploy state
|
||||
*/
|
||||
final case class TryDeploy(state : DriveState.Value)
|
||||
/**
|
||||
* A message for instigating a change to an undeploy state.
|
||||
* @param state the new undeploy state
|
||||
*/
|
||||
final case class TryUndeploy(state : DriveState.Value)
|
||||
/**
|
||||
* A response message to report successful deploy change.
|
||||
* @param obj the object being deployed
|
||||
* @param state the new deploy state
|
||||
*/
|
||||
final case class CanDeploy(obj : DeploymentObject, state : DriveState.Value)
|
||||
/**
|
||||
* A response message to report successful undeploy change.
|
||||
* @param obj the object being undeployed
|
||||
* @param state the new undeploy state
|
||||
*/
|
||||
final case class CanUndeploy(obj : DeploymentObject, state : DriveState.Value)
|
||||
/**
|
||||
* A response message to report an unsuccessful deployment change.
|
||||
* @param obj the object being changed
|
||||
* @param to_state the attempted deployment state
|
||||
* @param reason a string explaining why the state can not or will not change
|
||||
*/
|
||||
final case class CanNotChangeDeployment(obj : DeploymentObject, to_state : DriveState.Value, reason : String)
|
||||
|
||||
/**
|
||||
* Given a starting deployment state, provide the next deployment state in a sequence.<br>
|
||||
* <br>
|
||||
* Two sequences are defined.
|
||||
* The more elaborate sequence proceeds from `Mobile --> Deploying --> Deployed --> Undeploying --> Mobile`.
|
||||
* This is the standard in-game deploy cycle.
|
||||
* The sequence void of complexity is `State7 --> State7`.
|
||||
* `State7` is an odd condition possessed mainly by vehicles that do not deploy.
|
||||
* @param from_state the original deployment state
|
||||
* @return the deployment state that is being transitioned
|
||||
*/
|
||||
def NextState(from_state : DriveState.Value) : DriveState.Value = {
|
||||
from_state match {
|
||||
case DriveState.Mobile => DriveState.Deploying
|
||||
case DriveState.Deploying => DriveState.Deployed
|
||||
case DriveState.Deployed => DriveState.Undeploying
|
||||
case DriveState.Undeploying => DriveState.Mobile
|
||||
case DriveState.State7 => DriveState.State7
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this `state` considered one of "deploy?"
|
||||
* @param state the state to check
|
||||
* @return yes, if it is a valid state; otherwise, false
|
||||
*/
|
||||
def CheckForDeployState(state : DriveState.Value) : Boolean =
|
||||
state == DriveState.Deploying || state == DriveState.Deployed
|
||||
/**
|
||||
* Is this `state` considered one of "undeploy?"
|
||||
* @param state the state to check
|
||||
* @return yes, if it is a valid state; otherwise, false
|
||||
*/
|
||||
def CheckForUndeployState(state : DriveState.Value) : Boolean =
|
||||
state == DriveState.Undeploying || state == DriveState.Mobile || state == DriveState.State7
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.deploy
|
||||
|
||||
import akka.actor.Actor
|
||||
|
||||
/**
|
||||
* The logic governing `Deployment` objects that use the following messages:
|
||||
* `TryDeploymentChange`,
|
||||
* `TryDeploy`,
|
||||
* and `TryUndeploy`.
|
||||
* This is a mix-in trait for combining with existing `Receive` logic.
|
||||
* @see `Deployment`
|
||||
* @see `DriveState`
|
||||
*/
|
||||
trait DeploymentBehavior {
|
||||
this : Actor =>
|
||||
|
||||
def DeploymentObject : Deployment.DeploymentObject
|
||||
|
||||
val deployBehavior : Receive = {
|
||||
case Deployment.TryDeploymentChange(state) =>
|
||||
val obj = DeploymentObject
|
||||
if(Deployment.NextState(obj.DeploymentState) == state
|
||||
&& (obj.DeploymentState = state) == state) {
|
||||
if(Deployment.CheckForDeployState(state)) {
|
||||
sender ! Deployment.CanDeploy(obj, state)
|
||||
}
|
||||
else { //may need to check in future
|
||||
sender ! Deployment.CanUndeploy(obj, state)
|
||||
}
|
||||
}
|
||||
else {
|
||||
sender ! Deployment.CanNotChangeDeployment(obj, state, "incorrect transition state")
|
||||
}
|
||||
|
||||
case Deployment.TryDeploy(state) =>
|
||||
val obj = DeploymentObject
|
||||
if(Deployment.CheckForDeployState(state)
|
||||
&& Deployment.NextState(obj.DeploymentState) == state
|
||||
&& (obj.DeploymentState = state) == state) {
|
||||
sender ! Deployment.CanDeploy(obj, state)
|
||||
}
|
||||
else {
|
||||
sender ! Deployment.CanNotChangeDeployment(obj, state, "incorrect deploy transition state")
|
||||
}
|
||||
|
||||
case Deployment.TryUndeploy(state) =>
|
||||
val obj = DeploymentObject
|
||||
if(Deployment.CheckForUndeployState(state)
|
||||
&& Deployment.NextState(obj.DeploymentState) == state
|
||||
&& (obj.DeploymentState = state) == state) {
|
||||
sender ! Deployment.CanUndeploy(obj, state)
|
||||
}
|
||||
else {
|
||||
sender ! Deployment.CanNotChangeDeployment(obj, state, "incorrect undeploy transition state")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import akka.actor.Actor
|
|||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.serverobject.mount.MountableBehavior
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.deploy.DeploymentBehavior
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Vehicle`.<br>
|
||||
|
|
@ -15,18 +16,22 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi
|
|||
*/
|
||||
class VehicleControl(vehicle : Vehicle) extends Actor
|
||||
with FactionAffinityBehavior.Check
|
||||
with DeploymentBehavior
|
||||
with MountableBehavior.Mount
|
||||
with MountableBehavior.Dismount {
|
||||
//make control actors belonging to utilities when making control actor belonging to vehicle
|
||||
vehicle.Utilities.foreach({case (_, util) => util.Setup })
|
||||
|
||||
def MountableObject = vehicle //do not add type!
|
||||
def MountableObject = vehicle
|
||||
|
||||
def FactionObject : FactionAffinity = vehicle
|
||||
def FactionObject = vehicle
|
||||
|
||||
def DeploymentObject = vehicle
|
||||
|
||||
def receive : Receive = Enabled
|
||||
|
||||
def Enabled : Receive = checkBehavior
|
||||
.orElse(deployBehavior)
|
||||
.orElse(mountBehavior)
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
|
|
|
|||
|
|
@ -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.{DriveState, Vector3}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
|
|
@ -22,8 +22,7 @@ import scodec.codecs._
|
|||
* This packet has nothing to do with ACE deployables.
|
||||
* @param player_guid the player requesting the deployment
|
||||
* @param vehicle_guid the vehicle to be deployed
|
||||
* @param unk1 na;
|
||||
* usually 2
|
||||
* @param deploy_state either requests for a specific deployment state or assignment of the requested state
|
||||
* @param unk2 na;
|
||||
* usually 0
|
||||
* @param unk3 na
|
||||
|
|
@ -31,7 +30,7 @@ import scodec.codecs._
|
|||
*/
|
||||
final case class DeployRequestMessage(player_guid : PlanetSideGUID,
|
||||
vehicle_guid : PlanetSideGUID,
|
||||
unk1 : Int,
|
||||
deploy_state : DriveState.Value,
|
||||
unk2 : Int,
|
||||
unk3 : Boolean,
|
||||
pos : Vector3)
|
||||
|
|
@ -44,8 +43,8 @@ final case class DeployRequestMessage(player_guid : PlanetSideGUID,
|
|||
object DeployRequestMessage extends Marshallable[DeployRequestMessage] {
|
||||
implicit val codec : Codec[DeployRequestMessage] = (
|
||||
("player_guid" | PlanetSideGUID.codec) ::
|
||||
("deploy_guid" | PlanetSideGUID.codec) ::
|
||||
("unk1" | uint(3)) ::
|
||||
("vehicle_guid" | PlanetSideGUID.codec) ::
|
||||
("deploy_state" | DriveState.codec) ::
|
||||
("unk2" | uint(5)) ::
|
||||
("unk3" | bool) ::
|
||||
("pos" | Vector3.codec_pos)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.packet.game.objectcreate
|
||||
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import net.psforever.types.{DriveState, PlanetSideEmpire}
|
||||
|
||||
/**
|
||||
* A compilation of the common `*Data` objects that would be used for stock game objects.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.game.objectcreate
|
||||
import net.psforever.packet.Marshallable
|
||||
import net.psforever.packet.{Marshallable, PacketHelpers}
|
||||
import scodec.Attempt.{Failure, Successful}
|
||||
import scodec.{Attempt, Codec, Err}
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
import net.psforever.types.DriveState
|
||||
|
||||
/**
|
||||
* An `Enumeration` of the various formats that known structures that the stream of bits for `VehicleData` can assume.
|
||||
*/
|
||||
|
|
@ -141,6 +143,8 @@ object VehicleData extends Marshallable[VehicleData] {
|
|||
new VehicleData(basic, unk1, health, unk2>0, false, driveState, unk3, unk5>0, false, Some(unk4), inventory)(VehicleFormat.Variant)
|
||||
}
|
||||
|
||||
private val driveState8u = PacketHelpers.createEnumerationCodec(DriveState, uint8L)
|
||||
|
||||
/**
|
||||
* `Codec` for the "utility" format.
|
||||
*/
|
||||
|
|
@ -192,7 +196,7 @@ object VehicleData extends Marshallable[VehicleData] {
|
|||
("health" | uint8L) ::
|
||||
("unk2" | bool) :: //usually 0
|
||||
("no_mount_points" | bool) ::
|
||||
("driveState" | DriveState.codec) :: //used for deploy state
|
||||
("driveState" | driveState8u) :: //used for deploy state
|
||||
("unk3" | bool) :: //unknown but generally false; can cause stream misalignment if set when unexpectedly
|
||||
("unk4" | bool) ::
|
||||
("cloak" | bool) :: //cloak as wraith, phantasm
|
||||
|
|
|
|||
|
|
@ -1,26 +1,24 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.game.objectcreate
|
||||
package net.psforever.types
|
||||
|
||||
import net.psforever.packet.PacketHelpers
|
||||
import scodec.codecs._
|
||||
import scodec.codecs.uint
|
||||
|
||||
/**
|
||||
* An `Enumeration` of the mobility states of vehicles.<br>
|
||||
* <br>
|
||||
* In general, two important mobility states exist - `Mobile` and "deployed."
|
||||
* There are three stages of a formal deployment.
|
||||
* In general, two important mobility states exist - `Mobile` and `Deployed`.
|
||||
* There are stages of a formal deployment.
|
||||
* For any deployment state other than the defined ones, the vehicle assumes it is in one of the transitional states.
|
||||
* If the target vehicle has no deployment behavior, a non-`Mobile` value will not affect it.
|
||||
*/
|
||||
object DriveState extends Enumeration {
|
||||
type Type = Value
|
||||
|
||||
val Mobile = Value(0) //drivable
|
||||
val Undeployed = Value(1) //stationary
|
||||
val Unavailable = Value(2) //stationary, partial activation
|
||||
val Deployed = Value(3) //stationary, full activation
|
||||
|
||||
val Mobile = Value(0)
|
||||
val Undeploying = Value(1)
|
||||
val Deploying = Value(2)
|
||||
val Deployed = Value(3)
|
||||
val State7 = Value(7) //unknown; not encountered on a vehicle that can deploy; functions like Mobile
|
||||
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L)
|
||||
}
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint(3))
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ package game
|
|||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
import scodec.bits._
|
||||
|
||||
class DeployRequestMessageTest extends Specification {
|
||||
|
|
@ -12,10 +12,10 @@ class DeployRequestMessageTest extends Specification {
|
|||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case DeployRequestMessage(player_guid, vehicle_guid, unk1, unk2, unk3, pos) =>
|
||||
case DeployRequestMessage(player_guid, vehicle_guid, deploy_state, unk2, unk3, pos) =>
|
||||
player_guid mustEqual PlanetSideGUID(75)
|
||||
vehicle_guid mustEqual PlanetSideGUID(380)
|
||||
unk1 mustEqual 2
|
||||
deploy_state mustEqual DriveState.Deploying
|
||||
unk2 mustEqual 0
|
||||
unk3 mustEqual false
|
||||
pos.x mustEqual 4060.1953f
|
||||
|
|
@ -30,7 +30,8 @@ class DeployRequestMessageTest extends Specification {
|
|||
val msg = DeployRequestMessage(
|
||||
PlanetSideGUID(75),
|
||||
PlanetSideGUID(380),
|
||||
2, 0, false,
|
||||
DriveState.Deploying,
|
||||
0, false,
|
||||
Vector3(4060.1953f, 2218.8281f, 155.32812f)
|
||||
)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
|
|
|||
197
common/src/test/scala/objects/DeploymentTest.scala
Normal file
197
common/src/test/scala/objects/DeploymentTest.scala
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{Actor, ActorSystem, Props}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.objects.serverobject.deploy.{Deployment, DeploymentBehavior}
|
||||
import net.psforever.types.{DriveState, PlanetSideEmpire}
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class DeploymentTest extends Specification {
|
||||
"Deployment" should {
|
||||
"construct" in {
|
||||
val obj = new DeploymentTest.DeploymentObject()
|
||||
obj.DeploymentState mustEqual DriveState.Mobile
|
||||
obj.DeployTime mustEqual 0
|
||||
obj.UndeployTime mustEqual 0
|
||||
}
|
||||
|
||||
"change deployment state" in {
|
||||
val obj = new DeploymentTest.DeploymentObject()
|
||||
obj.DeploymentState mustEqual DriveState.Mobile
|
||||
|
||||
obj.DeploymentState = DriveState.Deployed
|
||||
obj.DeploymentState mustEqual DriveState.Deployed
|
||||
obj.DeploymentState = DriveState.Deploying
|
||||
obj.DeploymentState mustEqual DriveState.Deploying
|
||||
obj.DeploymentState = DriveState.Undeploying
|
||||
obj.DeploymentState mustEqual DriveState.Undeploying
|
||||
obj.DeploymentState = DriveState.State7
|
||||
obj.DeploymentState mustEqual DriveState.State7
|
||||
}
|
||||
|
||||
"have custom deployment time by object" in {
|
||||
val ams = Vehicle(GlobalDefinitions.ams)
|
||||
(ams.DeployTime == 0) mustEqual false //not default
|
||||
(ams.UndeployTime == 0) mustEqual false //not default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior1Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"construct" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.Actor != Actor.noSender)
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior2Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"change following a deployment cycle using TryDeployChange" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
//to Deploying
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Deploying)
|
||||
val reply1 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply1.isInstanceOf[Deployment.CanDeploy])
|
||||
assert(reply1.asInstanceOf[Deployment.CanDeploy].obj == obj)
|
||||
assert(reply1.asInstanceOf[Deployment.CanDeploy].state == DriveState.Deploying)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Deployed)
|
||||
val reply2 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply2.isInstanceOf[Deployment.CanDeploy])
|
||||
assert(reply2.asInstanceOf[Deployment.CanDeploy].obj == obj)
|
||||
assert(reply2.asInstanceOf[Deployment.CanDeploy].state == DriveState.Deployed)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Undeploying)
|
||||
val reply3 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply3.isInstanceOf[Deployment.CanUndeploy])
|
||||
assert(reply3.asInstanceOf[Deployment.CanUndeploy].obj == obj)
|
||||
assert(reply3.asInstanceOf[Deployment.CanUndeploy].state == DriveState.Undeploying)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Mobile)
|
||||
val reply4 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply4.isInstanceOf[Deployment.CanUndeploy])
|
||||
assert(reply4.asInstanceOf[Deployment.CanUndeploy].obj == obj)
|
||||
assert(reply4.asInstanceOf[Deployment.CanUndeploy].state == DriveState.Mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior3Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"change following a deployment cycle using TryDeploy and TryUndeploy" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
//to Deploying
|
||||
obj.Actor ! Deployment.TryDeploy(DriveState.Deploying)
|
||||
val reply1 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply1.isInstanceOf[Deployment.CanDeploy])
|
||||
assert(reply1.asInstanceOf[Deployment.CanDeploy].obj == obj)
|
||||
assert(reply1.asInstanceOf[Deployment.CanDeploy].state == DriveState.Deploying)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryDeploy(DriveState.Deployed)
|
||||
val reply2 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply2.isInstanceOf[Deployment.CanDeploy])
|
||||
assert(reply2.asInstanceOf[Deployment.CanDeploy].obj == obj)
|
||||
assert(reply2.asInstanceOf[Deployment.CanDeploy].state == DriveState.Deployed)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryUndeploy(DriveState.Undeploying)
|
||||
val reply3 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply3.isInstanceOf[Deployment.CanUndeploy])
|
||||
assert(reply3.asInstanceOf[Deployment.CanUndeploy].obj == obj)
|
||||
assert(reply3.asInstanceOf[Deployment.CanUndeploy].state == DriveState.Undeploying)
|
||||
//to Deployed
|
||||
obj.Actor ! Deployment.TryUndeploy(DriveState.Mobile)
|
||||
val reply4 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply4.isInstanceOf[Deployment.CanUndeploy])
|
||||
assert(reply4.asInstanceOf[Deployment.CanUndeploy].obj == obj)
|
||||
assert(reply4.asInstanceOf[Deployment.CanUndeploy].state == DriveState.Mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior4Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"not deploy to an out of order state" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Deployed)
|
||||
val reply1 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply1.isInstanceOf[Deployment.CanNotChangeDeployment])
|
||||
assert(reply1.asInstanceOf[Deployment.CanNotChangeDeployment].obj == obj)
|
||||
assert(reply1.asInstanceOf[Deployment.CanNotChangeDeployment].to_state == DriveState.Deployed)
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
|
||||
obj.Actor ! Deployment.TryDeploy(DriveState.Deployed)
|
||||
val reply2 = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply2.isInstanceOf[Deployment.CanNotChangeDeployment])
|
||||
assert(reply2.asInstanceOf[Deployment.CanNotChangeDeployment].obj == obj)
|
||||
assert(reply2.asInstanceOf[Deployment.CanNotChangeDeployment].to_state == DriveState.Deployed)
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior5Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"not deploy to an undeploy state" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Deploying)
|
||||
receiveOne(Duration.create(100, "ms")) //consume
|
||||
obj.Actor ! Deployment.TryDeploymentChange(DriveState.Deployed)
|
||||
receiveOne(Duration.create(100, "ms")) //consume
|
||||
assert(obj.DeploymentState == DriveState.Deployed)
|
||||
|
||||
obj.Actor ! Deployment.TryDeploy(DriveState.Undeploying)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Deployment.CanNotChangeDeployment])
|
||||
assert(reply.asInstanceOf[Deployment.CanNotChangeDeployment].obj == obj)
|
||||
assert(reply.asInstanceOf[Deployment.CanNotChangeDeployment].to_state == DriveState.Undeploying)
|
||||
assert(obj.DeploymentState == DriveState.Deployed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeploymentBehavior6Test extends ActorTest {
|
||||
"Deployment" should {
|
||||
"not undeploy to a deploy state" in {
|
||||
val obj = DeploymentTest.SetUpAgent
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
|
||||
obj.Actor ! Deployment.TryUndeploy(DriveState.Deploying)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Deployment.CanNotChangeDeployment])
|
||||
assert(reply.asInstanceOf[Deployment.CanNotChangeDeployment].obj == obj)
|
||||
assert(reply.asInstanceOf[Deployment.CanNotChangeDeployment].to_state == DriveState.Deploying)
|
||||
assert(obj.DeploymentState == DriveState.Mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object DeploymentTest {
|
||||
class DeploymentObject extends PlanetSideServerObject with Deployment {
|
||||
def Faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
def Definition = null
|
||||
}
|
||||
|
||||
private class DeploymentControl(obj : Deployment.DeploymentObject) extends Actor
|
||||
with DeploymentBehavior {
|
||||
override def DeploymentObject = obj
|
||||
def receive = deployBehavior.orElse { case _ => }
|
||||
}
|
||||
|
||||
def SetUpAgent(implicit system : ActorSystem) = {
|
||||
val obj = new DeploymentObject()
|
||||
obj.Actor = system.actorOf(Props(classOf[DeploymentControl], obj), "test")
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
|
|||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.deploy.Deployment
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
||||
|
|
@ -330,6 +331,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(guid, unk1, unk2)))
|
||||
}
|
||||
|
||||
case VehicleResponse.DeployRequest(object_guid, state, unk1, unk2, pos) =>
|
||||
if(player.GUID != guid) {
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(guid, object_guid, state, unk1, unk2, pos)))
|
||||
}
|
||||
|
||||
case VehicleResponse.InventoryState(obj, parent_guid, start, con_data) =>
|
||||
if(player.GUID != guid) {
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
|
|
@ -399,6 +405,50 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case _ => ;
|
||||
}
|
||||
|
||||
case Deployment.CanDeploy(obj, state) =>
|
||||
val vehicle_guid = obj.GUID
|
||||
if(state == DriveState.Deploying) {
|
||||
log.info(s"DeployRequest: $obj transitioning to deploy state")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, obj.Position)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, obj.Position))
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.scheduleOnce(obj.DeployTime milliseconds, obj.Actor, Deployment.TryDeploy(DriveState.Deployed))
|
||||
}
|
||||
else if(state == DriveState.Deployed) {
|
||||
log.info(s"DeployRequest: $obj has been Deployed")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, obj.Position)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, obj.Position))
|
||||
DeploymentActivities(obj)
|
||||
//...
|
||||
}
|
||||
else {
|
||||
CanNotChangeDeployment(obj, state, "incorrect deploy state")
|
||||
}
|
||||
|
||||
case Deployment.CanUndeploy(obj, state) =>
|
||||
val vehicle_guid = obj.GUID
|
||||
if(state == DriveState.Undeploying) {
|
||||
log.info(s"DeployRequest: $obj transitioning to undeploy state")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.scheduleOnce(obj.UndeployTime milliseconds, obj.Actor, Deployment.TryUndeploy(DriveState.Mobile))
|
||||
}
|
||||
else if(state == DriveState.Mobile) {
|
||||
log.info(s"DeployRequest: $obj is Mobile")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
//...
|
||||
}
|
||||
else {
|
||||
CanNotChangeDeployment(obj, state, "incorrect undeploy state")
|
||||
}
|
||||
|
||||
case Deployment.CanNotChangeDeployment(obj, state, reason) =>
|
||||
CanNotChangeDeployment(obj, state, reason)
|
||||
|
||||
case Door.DoorMessage(tplayer, msg, order) =>
|
||||
val door_guid = msg.object_guid
|
||||
order match {
|
||||
|
|
@ -2096,24 +2146,20 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
}
|
||||
|
||||
case msg @ DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, pos) =>
|
||||
log.info("DeployRequest: " + msg)
|
||||
//LOCAL FUNCTIONALITY ONLY FOR THIS BRANCH
|
||||
val player_guid = player.GUID
|
||||
if(unk1 == 2) { // deploy AMS
|
||||
//sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity,49,1))) // TODO : ANT ? With increment when loading NTU ?
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
Thread.sleep(1000) // 2 seconds
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, 3, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 10, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 11, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 12, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 13, 1)))
|
||||
case msg @ DeployRequestMessage(player_guid, vehicle_guid, deploy_state, unk2, unk3, pos) =>
|
||||
log.info(s"DeployRequest: $msg")
|
||||
if(player.VehicleOwned == Some(vehicle_guid) && player.VehicleOwned == player.VehicleSeated) {
|
||||
continent.GUID(vehicle_guid) match {
|
||||
case Some(obj : Vehicle) =>
|
||||
obj.Actor ! Deployment.TryDeploymentChange(deploy_state)
|
||||
|
||||
case _ =>
|
||||
log.error(s"DeployRequest: can not find $vehicle_guid in scope; removing ownership to mitigate confusion")
|
||||
player.VehicleOwned = None
|
||||
}
|
||||
}
|
||||
else if(unk1 == 1) { // undeploy AMS
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
Thread.sleep(1000) // 2 seconds
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, 0, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
else {
|
||||
log.warn(s"DeployRequest: $player does not own the deploying $vehicle_guid object")
|
||||
}
|
||||
|
||||
case msg @ AvatarGrenadeStateMessage(player_guid, state) =>
|
||||
|
|
@ -2607,12 +2653,18 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
/**
|
||||
* Temporary function that iterates over vehicle permissions and turns them into `PlanetsideAttributeMessage` packets.<br>
|
||||
* <br>
|
||||
* 2 November 2017
|
||||
* 2 November 2017:<br>
|
||||
* Unexpected behavior causes seat mount points to become blocked when a new driver claims the vehicle.
|
||||
* For the purposes of ensuring that other players are always aware of the proper permission state of the trunk and seats,
|
||||
* packets are intentionally dispatched to the current client to update the states.
|
||||
* Perform this action just after any instance where the client would initially gain awareness of the vehicle.
|
||||
* The most important examples include either the player or the vehicle itself spawning in for the first time.
|
||||
* The most important examples include either the player or the vehicle itself spawning in for the first time.<br>
|
||||
* <br>
|
||||
* 20 February 2018:<br>
|
||||
* Occasionally, during deployment, local(?) vehicle seat access permissions may change.
|
||||
* This results in players being locked into their own vehicle.
|
||||
* Reloading vehicle permissions supposedly ensures the seats will be properly available.
|
||||
* This is considered a client issue; but, somehow, it also impacts server operation somehow.
|
||||
* @param vehicle the `Vehicle`
|
||||
*/
|
||||
def ReloadVehicleAccessPermissions(vehicle : Vehicle) : Unit = {
|
||||
|
|
@ -2964,6 +3016,38 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform specific operations depending on the target of deployment.
|
||||
* @param obj the object that has deployed
|
||||
*/
|
||||
def DeploymentActivities(obj : Deployment.DeploymentObject) : Unit = {
|
||||
obj match {
|
||||
case vehicle : Vehicle =>
|
||||
//TODO we should not have to do this imho
|
||||
ReloadVehicleAccessPermissions(vehicle)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common reporting behavior when a `Deployment` object fails to properly transition between states.
|
||||
* @param obj the game object that could not
|
||||
* @param state the `DriveState` that could not be promoted
|
||||
* @param reason a string explaining why the state can not or will not change
|
||||
*/
|
||||
def CanNotChangeDeployment(obj : PlanetSideServerObject with Deployment, state : DriveState.Value, reason : String) : Unit = {
|
||||
val mobileShift : String = if(obj.DeploymentState != DriveState.Mobile) {
|
||||
obj.DeploymentState = DriveState.Mobile
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, false, Vector3.Zero)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, false, Vector3.Zero))
|
||||
"; enforcing Mobile deployment state"
|
||||
}
|
||||
else {
|
||||
""
|
||||
}
|
||||
log.error(s"DeployRequest: $obj can not transition to $state - $reason$mobileShift")
|
||||
}
|
||||
|
||||
def failWithError(error : String) = {
|
||||
log.error(error)
|
||||
sendResponse(PacketCoding.CreateControlPacket(ConnectionClose()))
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ import net.psforever.objects.equipment.Equipment
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
|
||||
object VehicleAction {
|
||||
trait Action
|
||||
|
||||
final case class Awareness(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class ChildObjectState(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, pitch : Float, yaw : Float) extends Action
|
||||
final case class DeployRequest(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, state : DriveState.Value, unk1 : Int, unk2 : Boolean, pos : Vector3) extends Action
|
||||
final case class DismountVehicle(player_guid : PlanetSideGUID, unk1 : Int, unk2 : Boolean) extends Action
|
||||
final case class InventoryState(player_guid : PlanetSideGUID, obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Action
|
||||
final case class KickPassenger(player_guid : PlanetSideGUID, unk1 : Int, unk2 : Boolean, vehicle_guid : PlanetSideGUID) extends Action
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ package services.vehicle
|
|||
import net.psforever.objects.{PlanetSideGameObject, Vehicle}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
|
||||
object VehicleResponse {
|
||||
trait Response
|
||||
|
||||
final case class Awareness(vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class ChildObjectState(object_guid : PlanetSideGUID, pitch : Float, yaw : Float) extends Response
|
||||
final case class DeployRequest(object_guid : PlanetSideGUID, state : DriveState.Value, unk1 : Int, unk2 : Boolean, pos : Vector3) extends Response
|
||||
final case class DismountVehicle(unk1 : Int, unk2 : Boolean) extends Response
|
||||
final case class InventoryState(obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Response
|
||||
final case class KickPassenger(unk1 : Int, unk2 : Boolean, vehicle_guid : PlanetSideGUID) extends Response
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
package services.vehicle
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import services.vehicle.support.{DeconstructionActor, DelayedDeconstructionActor, VehicleContextActor}
|
||||
import services.{GenericEventBus, Service}
|
||||
|
||||
|
|
@ -49,14 +47,18 @@ class VehicleService extends Actor {
|
|||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.ChildObjectState(object_guid, pitch, yaw))
|
||||
)
|
||||
case VehicleAction.InventoryState(player_guid, obj, parent_guid, start, con_data) =>
|
||||
case VehicleAction.DeployRequest(player_guid, object_guid, state, unk1, unk2, pos) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.InventoryState(obj, parent_guid, start, con_data))
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.DeployRequest(object_guid, state, unk1, unk2, pos))
|
||||
)
|
||||
case VehicleAction.DismountVehicle(player_guid, unk1, unk2) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.DismountVehicle(unk1, unk2))
|
||||
)
|
||||
case VehicleAction.InventoryState(player_guid, obj, parent_guid, start, con_data) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.InventoryState(obj, parent_guid, start, con_data))
|
||||
)
|
||||
case VehicleAction.KickPassenger(player_guid, unk1, unk2, vehicle_guid) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.KickPassenger(unk1, unk2, vehicle_guid))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import net.psforever.types.{CharacterGender, ExoSuitType, PlanetSideEmpire, Vect
|
|||
import services.Service
|
||||
import services.avatar._
|
||||
|
||||
class AvatarService0Test extends ActorTest {
|
||||
class AvatarService1Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"construct" in {
|
||||
system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -15,7 +15,7 @@ class AvatarService0Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService1_1Test extends ActorTest {
|
||||
class AvatarService2Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -25,9 +25,9 @@ class AvatarService1_1Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService1_2Test extends ActorTest {
|
||||
class AvatarService3Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
|
|
@ -36,7 +36,7 @@ class AvatarService1_2Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService1_3Test extends ActorTest {
|
||||
class AvatarService4Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -47,7 +47,7 @@ class AvatarService1_3Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService2Test extends ActorTest {
|
||||
class AvatarService5Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass an unhandled message" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -58,7 +58,7 @@ class AvatarService2Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService3Test extends ActorTest {
|
||||
class ArmorChangedTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ArmorChanged" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -69,7 +69,7 @@ class AvatarService3Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService4Test extends ActorTest {
|
||||
class ConcealPlayerTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ConcealPlayer" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -80,7 +80,7 @@ class AvatarService4Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService5Test extends ActorTest {
|
||||
class EquipmentInHandTest extends ActorTest {
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
|
||||
"AvatarService" should {
|
||||
|
|
@ -93,21 +93,23 @@ class AvatarService5Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService6Test extends ActorTest {
|
||||
class EquipmentOnGroundTest extends ActorTest {
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(1)
|
||||
val cdata = toolDef.Packet.ConstructorData(tool).get
|
||||
|
||||
"AvatarService" should {
|
||||
"pass EquipmentOnGround" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.EquipmentOnGround(PlanetSideGUID(10), Vector3(300f, 200f, 100f), Vector3(450f, 300f, 150f), toolDef.ObjectId, PlanetSideGUID(11), toolDef.Packet.ConstructorData(tool).get))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentOnGround(Vector3(300f, 200f, 100f), Vector3(450f, 300f, 150f), toolDef.ObjectId, PlanetSideGUID(11), toolDef.Packet.ConstructorData(tool).get)))
|
||||
service ! AvatarServiceMessage("test", AvatarAction.EquipmentOnGround(PlanetSideGUID(10), Vector3(300f, 200f, 100f), Vector3(450f, 300f, 150f), toolDef.ObjectId, PlanetSideGUID(11), cdata))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentOnGround(Vector3(300f, 200f, 100f), Vector3(450f, 300f, 150f), toolDef.ObjectId, PlanetSideGUID(11), cdata)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService7Test extends ActorTest {
|
||||
class LoadPlayerTest extends ActorTest {
|
||||
val obj = Player("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, 1)
|
||||
obj.GUID = PlanetSideGUID(10)
|
||||
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(11)
|
||||
|
|
@ -123,7 +125,7 @@ class AvatarService7Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService8Test extends ActorTest {
|
||||
class ObjectDeleteTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectDelete" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -137,7 +139,7 @@ class AvatarService8Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService9Test extends ActorTest {
|
||||
class ObjectHeldTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectHeld" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -148,7 +150,7 @@ class AvatarService9Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceATest extends ActorTest {
|
||||
class PlanetsideAttributeTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass PlanetsideAttribute" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -159,7 +161,7 @@ class AvatarServiceATest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceBTest extends ActorTest {
|
||||
class PlayerStateTest extends ActorTest {
|
||||
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)
|
||||
|
||||
"AvatarService" should {
|
||||
|
|
@ -172,7 +174,7 @@ class AvatarServiceBTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceCTest extends ActorTest {
|
||||
class ReloadTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass Reload" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -183,7 +185,7 @@ class AvatarServiceCTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceDTest extends ActorTest {
|
||||
class ChangeAmmoTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
|
|
@ -197,7 +199,7 @@ class AvatarServiceDTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceETest extends ActorTest {
|
||||
class ChangeFireModeTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
|
|
@ -211,7 +213,7 @@ class AvatarServiceETest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceF_1Test extends ActorTest {
|
||||
class ChangeFireStateStartTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Start" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -222,7 +224,7 @@ class AvatarServiceF_1Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarServiceF_2Test extends ActorTest {
|
||||
class ChangeFireStateStopTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Stop" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
|
|
@ -233,7 +235,7 @@ class AvatarServiceF_2Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class AvatarService01Test extends ActorTest {
|
||||
class WeaponDryFireTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass WeaponDryFire" in {
|
||||
val service = system.actorOf(Props[AvatarService], "service")
|
||||
239
pslogin/src/test/scala/VehicleServiceTest.scala
Normal file
239
pslogin/src/test/scala/VehicleServiceTest.scala
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects._
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types._
|
||||
import services.{Service, ServiceManager}
|
||||
import services.vehicle._
|
||||
|
||||
class VehicleService1Test extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"construct" in {
|
||||
system.actorOf(Props[VehicleService], "v-service")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleService2Test extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleService3Test extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleService4Test extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleService5Test extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass an unhandled message" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMsg()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AwarenessTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass Awareness" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.Awareness(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.Awareness(PlanetSideGUID(11))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChildObjectStateTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass ChildObjectState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.ChildObjectState(PlanetSideGUID(10), PlanetSideGUID(11), 1.2f, 3.4f))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeployRequestTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass DeployRequest" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.DeployRequest(PlanetSideGUID(10), PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DismountVehicleTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass DismountVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.DismountVehicle(PlanetSideGUID(10), 0, false))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.DismountVehicle(0, false)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InventoryStateTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13)
|
||||
val cdata = tool.Definition.Packet.ConstructorData(tool).get
|
||||
|
||||
"VehicleService" should {
|
||||
"pass InventoryState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.InventoryState(PlanetSideGUID(10), tool, PlanetSideGUID(11), 0, cdata))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.InventoryState(tool, PlanetSideGUID(11), 0, cdata)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KickPassengerTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass KickPassenger" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.KickPassenger(PlanetSideGUID(10), 0, false, PlanetSideGUID(11)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.KickPassenger(0, false, PlanetSideGUID(11))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoadVehicleTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.quadstealth)
|
||||
val cdata = vehicle.Definition.Packet.ConstructorData(vehicle).get
|
||||
|
||||
"VehicleService" should {
|
||||
"pass LoadVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.LoadVehicle(PlanetSideGUID(10), vehicle, 12, PlanetSideGUID(11), cdata))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MountVehicleTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass MountVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(10), PlanetSideGUID(11), 0))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.MountVehicle(PlanetSideGUID(11), 0)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SeatPermissionsTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass SeatPermissions" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.SeatPermissions(PlanetSideGUID(10), PlanetSideGUID(11), 0, 12L))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.SeatPermissions(PlanetSideGUID(11), 0, 12L)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class StowEquipmentTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
tool.GUID = PlanetSideGUID(12)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13)
|
||||
val toolDef = tool.Definition
|
||||
val cdata = tool.Definition.Packet.DetailedConstructorData(tool).get
|
||||
|
||||
"StowEquipment" should {
|
||||
"pass StowEquipment" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 0, tool))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.StowEquipment(PlanetSideGUID(11), 0, toolDef.ObjectId, tool.GUID, cdata)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnstowEquipmentTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass UnstowEquipment" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.UnstowEquipment(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.UnstowEquipment(PlanetSideGUID(11))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleStateTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
|
||||
"VehicleService" should {
|
||||
"pass VehicleState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.VehicleState(PlanetSideGUID(10), PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), Vector3(7.8f, 9.1f, 2.3f), Some(Vector3(4.5f, 6.7f, 8.9f)), Option(1), 2, 3, 4, false, true))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.VehicleState(PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), Vector3(7.8f, 9.1f, 2.3f), Some(Vector3(4.5f, 6.7f, 8.9f)), Option(1), 2, 3, 4, false, true)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object VehicleServiceTest {
|
||||
//decoy
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue