mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-03 12:10:22 +00:00
Zone-local Event Systems (#295)
* all matters related to vehicle events, including tests, adjusted so that the service actor internalizes a specific zone; major adjustments to the order fulfillment logic of vehicle spawn pads; removed a bunch of unnecessary things such as auto-drive guidance * all matters related to local events, including tests, adjusted so that the service actor internalizes a specific zone; special consideration for proximity units and tests; muted some excessive logging * all matters related to avatar events, including tests, adjusted so that the service actor internalizes a specific zone; special considerations for resource silos and painbox elements * explicit trait that acts as an owner of Amenity objects (Building and Vehicle); generalization of <obj>.Owner.Zone statement * reduced log spam from proximity terminal activity * tightened vehicle spawn pad control protocol; finally made the player re-appear if the vehicle doesn't spawn/mount correctly; pad operates independent of the person who submitted the current order so less chances for crash * adjusted workflow for vehicle spawn pad task management
This commit is contained in:
parent
885387b734
commit
9ec97f279a
47 changed files with 1393 additions and 2651 deletions
|
|
@ -9,9 +9,10 @@ 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.serverobject.structures.AmenityOwner
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vital.{DamageResistanceModel, StandardResistanceProfile, Vitality}
|
||||
import net.psforever.objects.zones.ZoneAware
|
||||
import net.psforever.objects.zones.{Zone, ZoneAware}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
|
|
@ -73,6 +74,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
with Deployment
|
||||
with Vitality
|
||||
with OwnableByPlayer
|
||||
with AmenityOwner
|
||||
with StandardResistanceProfile
|
||||
with Container {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.TR
|
||||
|
|
@ -84,8 +86,12 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
private var cloaked : Boolean = false
|
||||
private var flying : Boolean = false
|
||||
private var capacitor : Int = 0
|
||||
private var continent : String = "home2" //the zone id
|
||||
|
||||
/**
|
||||
* Normally, the vehicle is the resident of a `Zone` object and that is what it considers its "continent."
|
||||
* Since the `Vehicle` object can switch between `Zone` objects, however,
|
||||
* it may become useful to allow the vehicle to identify as belonging to its future zone earlier than reference assignment.
|
||||
*/
|
||||
private var continent : Option[String] = None //the zone id
|
||||
/**
|
||||
* Permissions control who gets to access different parts of the vehicle;
|
||||
* the groups are Driver (seat), Gunner (seats), Passenger (seats), and the Trunk
|
||||
|
|
@ -508,10 +514,25 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
*/
|
||||
def Definition : VehicleDefinition = vehicleDef
|
||||
|
||||
override def Continent : String = continent
|
||||
/**
|
||||
* When assigning a new `Zone` object for the `Vehicle` object, eliminate
|
||||
* @param zone a reference to the `Zone` object
|
||||
* @return a reference to the `Zone` object
|
||||
*/
|
||||
override def Zone_=(zone : Zone) : Zone = {
|
||||
continent = None
|
||||
super.Zone_=(zone)
|
||||
}
|
||||
|
||||
override def Continent : String = continent.getOrElse(Zone.Id)
|
||||
|
||||
/**
|
||||
* Give the `Vehicle` object a custom `Zone` identifier.
|
||||
* @param zoneId the custom identifier of the `Zone` object
|
||||
* @return the identifier of the `Zone` object
|
||||
*/
|
||||
override def Continent_=(zoneId : String) : String = {
|
||||
continent = zoneId
|
||||
continent = Some(zoneId)
|
||||
Continent
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import akka.actor.{ActorContext, ActorRef, Cancellable, Props}
|
||||
import akka.actor.{ActorContext, Cancellable, Props}
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.pad.process.{VehicleSpawnControlBase, VehicleSpawnControlConcealPlayer}
|
||||
import net.psforever.objects.zones.Zone
|
||||
|
|
@ -12,28 +12,32 @@ import scala.concurrent.ExecutionContext.Implicits.global
|
|||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad`.
|
||||
* The basic `VehicleSpawnControl` is the root of a simple tree of "spawn control" objects that chain to each other.
|
||||
* Each object performs on (or more than one related) actions upon the vehicle order that was submitted.<br>
|
||||
* An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad` entity.
|
||||
* The basic `VehicleSpawnControl` is the root of a sequence of "spawn control" objects that chain to each other.
|
||||
* Each object performs one (or more related) actions upon the vehicle order that was submitted.<br>
|
||||
* <br>
|
||||
* The purpose of the base actor is to serve as the entry point for the spawning process.
|
||||
* A spawn pad receives vehicle orders from an attached `Terminal` object.
|
||||
* The purpose of the base actor is to serve as the entry point for the spawning process
|
||||
* and to manage the order queue.
|
||||
* A spawn pad receives vehicle orders from a related `Terminal` object.
|
||||
* The control object accepts orders, enqueues them, and,
|
||||
* whenever prompted by a previous complete order or by an absence of active orders,
|
||||
* will select the first available order to be completed.
|
||||
* This order will be "tracked" and will be given to the first functional "spawn control" object of the process.
|
||||
* If the process is completed, or is ever aborted by any of the subsequent tasks,
|
||||
* control will propagate down back to this control object.
|
||||
* At this time, (or) once again, a new order can be submitted or will be selected.
|
||||
* @param pad the `VehicleSpawnPad` object being governed
|
||||
*/
|
||||
class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) with FactionAffinityBehavior.Check {
|
||||
/** a reminder sent to future customers */
|
||||
var periodicReminder : Cancellable = DefaultCancellable.obj
|
||||
/** a list of vehicle orders that have been submitted for this spawn pad */
|
||||
private var orders : List[VehicleSpawnControl.Order] = List.empty[VehicleSpawnControl.Order]
|
||||
var orders : List[VehicleSpawnControl.Order] = List.empty[VehicleSpawnControl.Order]
|
||||
/** the current vehicle order being acted upon;
|
||||
* used as a guard condition to control order processing rate */
|
||||
private var trackedOrder : Option[VehicleSpawnControl.Order] = None
|
||||
var trackedOrder : Option[VehicleSpawnControl.Order] = None
|
||||
/** how to process either the first order or every subsequent order */
|
||||
var handleOrderFunc : VehicleSpawnControl.Order => Unit = NewTasking
|
||||
|
||||
def LogId = ""
|
||||
|
||||
|
|
@ -55,13 +59,16 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase
|
|||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case VehicleSpawnPad.VehicleOrder(player, vehicle) =>
|
||||
trace(s"order from $player for $vehicle received")
|
||||
orders = orders :+ VehicleSpawnControl.Order(player, vehicle, sender)
|
||||
if(trackedOrder.isEmpty && orders.length == 1) {
|
||||
SelectOrder()
|
||||
trace(s"order from ${player.Name} for a ${vehicle.Definition.Name} received")
|
||||
try {
|
||||
handleOrderFunc(VehicleSpawnControl.Order(player, vehicle))
|
||||
}
|
||||
else {
|
||||
sender ! VehicleSpawnControl.RenderOrderRemainderMsg(orders.length + 1)
|
||||
catch {
|
||||
case _ : AssertionError if vehicle.HasGUID => //same as order being dropped
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(vehicle, pad.Owner.Zone)
|
||||
case _ : AssertionError => ; //shrug
|
||||
case e : Exception => //something unexpected
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
case VehicleSpawnControl.ProcessControl.GetNewOrder =>
|
||||
|
|
@ -89,7 +96,7 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase
|
|||
)
|
||||
}
|
||||
else {
|
||||
VehicleSpawnControl.BlockedReminder(entry, entry +: orders)
|
||||
BlockedReminder(entry, orders)
|
||||
}
|
||||
case None => ;
|
||||
periodicReminder.cancel
|
||||
|
|
@ -97,43 +104,143 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase
|
|||
|
||||
case VehicleSpawnControl.ProcessControl.Flush =>
|
||||
periodicReminder.cancel
|
||||
orders.foreach { VehicleSpawnControl.CancelOrder(_, Continent) }
|
||||
orders.foreach { CancelOrder }
|
||||
orders = Nil
|
||||
trackedOrder match {
|
||||
case Some(entry) =>
|
||||
VehicleSpawnControl.CancelOrder(entry, Continent)
|
||||
CancelOrder(entry)
|
||||
case None => ;
|
||||
}
|
||||
trackedOrder = None
|
||||
concealPlayer ! akka.actor.Kill //will cause the actor to restart, which will abort any trapped messages
|
||||
concealPlayer ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def SelectOrder() : Unit = {
|
||||
/**
|
||||
* Take this order - the "first order" - and immediately begin processing it.
|
||||
* All orders accepted in the meantime will be queued and a note about priority will be issued.
|
||||
* @param order the order being accepted
|
||||
*/
|
||||
def NewTasking(order : VehicleSpawnControl.Order) : Unit = {
|
||||
handleOrderFunc = QueuedTasking
|
||||
ProcessOrder(Some(order))
|
||||
}
|
||||
|
||||
/**
|
||||
* While an order is being processed,
|
||||
* all orders accepted in the meantime will be queued and a note about priority will be issued.
|
||||
* @param order the order being accepted
|
||||
*/
|
||||
def QueuedTasking(order : VehicleSpawnControl.Order) : Unit = {
|
||||
val name = order.driver.Name
|
||||
if((trackedOrder match {
|
||||
case Some(tracked) => !tracked.driver.Name.equals(name)
|
||||
case None => true
|
||||
}) && orders.forall { !_.driver.Name.equals(name) }) {
|
||||
//not a second order from an existing order's player
|
||||
orders = orders :+ order
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(name, VehicleSpawnPad.Reminders.Queue, Some(orders.length + 1))
|
||||
}
|
||||
else {
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(order, pad.Owner.Zone)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the next available queued order and begin processing it.
|
||||
*/
|
||||
def SelectOrder() : Unit = ProcessOrder(SelectFirstOrder())
|
||||
|
||||
/**
|
||||
* Select the next-available queued order if there is no current order being fulfilled.
|
||||
* If the queue has been exhausted, set functionality to prepare to accept the next order as a "first order."
|
||||
* @return the next-available order
|
||||
*/
|
||||
def SelectFirstOrder() : Option[VehicleSpawnControl.Order] = {
|
||||
trackedOrder match {
|
||||
case None =>
|
||||
periodicReminder.cancel
|
||||
val (completeOrder, remainingOrders) : (Option[VehicleSpawnControl.Order], List[VehicleSpawnControl.Order]) = orders match {
|
||||
case x :: Nil =>
|
||||
(Some(x), Nil)
|
||||
case x :: b =>
|
||||
trace(s"order backlog size: ${b.size}")
|
||||
VehicleSpawnControl.recursiveOrderReminder(b.iterator)
|
||||
(Some(x), b)
|
||||
case Nil =>
|
||||
handleOrderFunc = NewTasking
|
||||
(None, Nil)
|
||||
}
|
||||
orders = remainingOrders
|
||||
completeOrder match {
|
||||
case Some(entry) =>
|
||||
trace(s"processing next order - a ${entry.vehicle.Definition.Name} for ${entry.driver.Name}")
|
||||
trackedOrder = completeOrder //guard on
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, concealPlayer, VehicleSpawnControl.Process.ConcealPlayer(entry))
|
||||
case None =>
|
||||
trackedOrder = None
|
||||
}
|
||||
case Some(_) => ; //do not work on new orders
|
||||
completeOrder
|
||||
case Some(_) =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a new order is accepted, begin processing it.
|
||||
* Inform all customers whose orders are still queued of their priority number
|
||||
* and activate the guard to ensure multiple orders don't get processed at the same time.
|
||||
* @param order the order being accepted;
|
||||
* `None`, if no order found or submitted
|
||||
*/
|
||||
def ProcessOrder(order : Option[VehicleSpawnControl.Order]) : Unit = {
|
||||
periodicReminder.cancel
|
||||
order match {
|
||||
case Some(_order) =>
|
||||
recursiveOrderReminder(orders.iterator)
|
||||
trace(s"processing next order - a ${_order.vehicle.Definition.Name} for ${_order.driver.Name}")
|
||||
trackedOrder = order //guard on
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, concealPlayer, _order)
|
||||
case None => ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param blockedOrder the previous order whose vehicle is blocking the spawn pad from operating
|
||||
* @param recipients all of the other customers who will be receiving the message
|
||||
*/
|
||||
def BlockedReminder(blockedOrder : VehicleSpawnControl.Order, recipients : Seq[VehicleSpawnControl.Order]) : Unit = {
|
||||
val relevantRecipients = blockedOrder.vehicle.Seats(0).Occupant.orElse(pad.Owner.Zone.GUID(blockedOrder.vehicle.Owner)) match {
|
||||
case Some(p : Player) =>
|
||||
(VehicleSpawnControl.Order(p, blockedOrder.vehicle) +: recipients).iterator //who took possession of the vehicle
|
||||
case _ =>
|
||||
(blockedOrder +: recipients).iterator //who ordered the vehicle
|
||||
}
|
||||
recursiveBlockedReminder(relevantRecipients,
|
||||
if(blockedOrder.vehicle.Health == 0)
|
||||
Option("Clear the wreckage.")
|
||||
else
|
||||
None
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel this vehicle order and inform the person who made it, if possible.
|
||||
* @param entry the order being cancelled
|
||||
* @param context an `ActorContext` object for which to create the `TaskResolver` object
|
||||
*/
|
||||
def CancelOrder(entry : VehicleSpawnControl.Order)(implicit context : ActorContext) : Unit = {
|
||||
val vehicle = entry.vehicle
|
||||
if(vehicle.Seats.values.count(_.isOccupied) == 0) {
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(entry, pad.Owner.Zone)
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(entry.driver.Name, VehicleSpawnPad.Reminders.Cancelled)
|
||||
}
|
||||
}
|
||||
|
||||
@tailrec private final def recursiveBlockedReminder(iter : Iterator[VehicleSpawnControl.Order], cause : Option[Any]) : Unit = {
|
||||
if(iter.hasNext) {
|
||||
val recipient = iter.next
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(recipient.driver.Name, VehicleSpawnPad.Reminders.Blocked, cause)
|
||||
recursiveBlockedReminder(iter, cause)
|
||||
}
|
||||
}
|
||||
|
||||
@tailrec private final def recursiveOrderReminder(iter : Iterator[VehicleSpawnControl.Order], position : Int = 2) : Unit = {
|
||||
if(iter.hasNext) {
|
||||
val recipient = iter.next
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(recipient.driver.Name, VehicleSpawnPad.Reminders.Queue, Some(position))
|
||||
recursiveOrderReminder(iter, position + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -152,159 +259,35 @@ object VehicleSpawnControl {
|
|||
Flush
|
||||
= Value
|
||||
}
|
||||
/**
|
||||
* An `Enumeration` of the stages of a full vehicle spawning process, passing the current order being processed.
|
||||
* Messages in this group are used by the `receive` entry points of the multiple child objects
|
||||
* that perform the vehicle spawning operation.
|
||||
*/
|
||||
object Process {
|
||||
sealed class Order(entry : VehicleSpawnControl.Order)
|
||||
|
||||
final case class ConcealPlayer(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class LoadVehicle(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class SeatDriver(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class RailJackAction(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class ServerVehicleOverride(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class StartGuided(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class DriverVehicleControl(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
final case class FinalClearance(entry : VehicleSpawnControl.Order) extends Order(entry)
|
||||
}
|
||||
|
||||
/**
|
||||
* An entry that stores vehicle spawn pad spawning tasks (called "orders").
|
||||
* An entry that stores a vehicle spawn pad spawning task (called an "order").
|
||||
* @param driver the player who wants the vehicle
|
||||
* @param vehicle the vehicle
|
||||
* @param sendTo a callback `Actor` associated with the player (in other words, `WorldSessionActor`)
|
||||
*/
|
||||
final case class Order(driver : Player, vehicle : Vehicle, sendTo : ActorRef)
|
||||
|
||||
/**
|
||||
* Properly clean up a vehicle that has been registered, but not yet been spawned into the game world.<br>
|
||||
* <br>
|
||||
* Constructs a temporary `TaskResolver` to deal with the vehicle's registration status.
|
||||
* This "temporary" router will persist as if it were a `static` variable in some other language
|
||||
* due to the fact that the `ActorSystem` object will remember it existing.
|
||||
* After the primary task is complete, the router that was created is stopped so that it can be garbage collected.
|
||||
* We could re-use it theoretically, but the `context` might be untrustworthy.
|
||||
* @param entry the order being cancelled
|
||||
* @param zone the continent on which the vehicle was registered
|
||||
* @param context an `ActorContext` object for which to create the `TaskResolver` object
|
||||
*/
|
||||
def DisposeVehicle(entry : VehicleSpawnControl.Order, zone: Zone)(implicit context : ActorContext) : Unit = {
|
||||
import akka.actor.{ActorRef, PoisonPill}
|
||||
import akka.routing.SmallestMailboxPool
|
||||
import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
|
||||
import net.psforever.types.Vector3
|
||||
val vehicle = entry.vehicle
|
||||
vehicle.Position = Vector3.Zero
|
||||
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(entry.driver.GUID, zone.Id)
|
||||
|
||||
val router = context.actorOf(
|
||||
SmallestMailboxPool(10).props(Props[TaskResolver]),
|
||||
s"vehicle-spawn-control-emergency-decon-resolver-${System.nanoTime}"
|
||||
)
|
||||
router !
|
||||
TaskResolver.GiveTask(
|
||||
new Task() {
|
||||
private val localRouter = router
|
||||
|
||||
override def isComplete = Task.Resolution.Success
|
||||
|
||||
def Execute(resolver : ActorRef) : Unit = {
|
||||
resolver ! scala.util.Success(this)
|
||||
}
|
||||
|
||||
override def Cleanup() : Unit = { localRouter ! PoisonPill } //where the router is stopped
|
||||
}, List(GUIDTask.UnregisterVehicle(vehicle)(zone.GUID))
|
||||
)
|
||||
final case class Order(driver : Player, vehicle : Vehicle) {
|
||||
assert(driver.HasGUID, s"when ordering a vehicle, the prospective driver ${driver.Name} does not have a GUID")
|
||||
assert(vehicle.HasGUID, s"when ordering a vehicle, the ${vehicle.Definition.Name} does not have a GUID")
|
||||
val DriverGUID = driver.GUID
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly clean up a vehicle that has been registered and spawned into the game world.
|
||||
* Call this downstream of "`ConcealPlayer`".
|
||||
* @param entry the order being cancelled
|
||||
* @param zone the continent on which the vehicle was registered
|
||||
*/
|
||||
def DisposeSpawnedVehicle(entry : VehicleSpawnControl.Order, zone: Zone) : Unit = {
|
||||
//TODO this cleanup will handle the vehicle; but, the former driver may be thrown into the void
|
||||
zone.VehicleEvents ! VehicleSpawnPad.DisposeVehicle(entry.vehicle, zone)
|
||||
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(entry.driver.GUID, zone.Id)
|
||||
DisposeSpawnedVehicle(entry.vehicle, zone)
|
||||
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(entry.DriverGUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remind a customer how long it will take for their vehicle order to be processed.
|
||||
* @param position position in the queue
|
||||
* @return an index-appropriate `VehicleSpawnPad.PeriodicReminder` object
|
||||
*/
|
||||
def RenderOrderRemainderMsg(position : Int) : VehicleSpawnPad.PeriodicReminder = {
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"$position"))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param blockedOrder the previous order whose vehicle is blocking the spawn pad from operating
|
||||
* @param recipients all of the customers who will be receiving the message
|
||||
*/
|
||||
def BlockedReminder(blockedOrder : VehicleSpawnControl.Order, recipients : Seq[VehicleSpawnControl.Order]) : Unit = {
|
||||
val wrecked : Option[Any] = if(blockedOrder.vehicle.Health == 0) {
|
||||
Option("Clear the wreckage.")
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
VehicleSpawnControl.recursiveBlockedReminder(recipients.iterator, wrecked)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel this vehicle order and inform the person who made it, if possible.
|
||||
* @param entry the order being cancelled
|
||||
* Properly clean up a vehicle that has been registered and spawned into the game world.
|
||||
* @param vehicle the vehicle being cancelled
|
||||
* @param zone the continent on which the vehicle was registered
|
||||
* @param context an `ActorContext` object for which to create the `TaskResolver` object
|
||||
*/
|
||||
def CancelOrder(entry : VehicleSpawnControl.Order, zone : Zone)(implicit context : ActorContext) : Unit = {
|
||||
val vehicle = entry.vehicle
|
||||
if(vehicle.Seats.values.count(_.isOccupied) == 0) {
|
||||
if(vehicle.Actor != ActorRef.noSender) {
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(entry, zone)
|
||||
}
|
||||
else {
|
||||
VehicleSpawnControl.DisposeVehicle(entry, zone)
|
||||
}
|
||||
if(entry.sendTo != ActorRef.noSender) {
|
||||
entry.sendTo ! VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Cancelled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @tailrec private final def recursiveFindOrder(iter : Iterator[VehicleSpawnControl.Order], target : ActorRef, index : Int = 0) : Option[Int] = {
|
||||
// if(!iter.hasNext) {
|
||||
// None
|
||||
// }
|
||||
// else {
|
||||
// val recipient = iter.next
|
||||
// if(recipient.sendTo == target) {
|
||||
// Some(index)
|
||||
// }
|
||||
// else {
|
||||
// recursiveFindOrder(iter, target, index + 1)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@tailrec private final def recursiveBlockedReminder(iter : Iterator[VehicleSpawnControl.Order], cause : Option[Any]) : Unit = {
|
||||
if(iter.hasNext) {
|
||||
val recipient = iter.next
|
||||
recipient.sendTo ! VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, cause)
|
||||
recursiveBlockedReminder(iter, cause)
|
||||
}
|
||||
}
|
||||
|
||||
@tailrec private final def recursiveOrderReminder(iter : Iterator[VehicleSpawnControl.Order], position : Int = 2) : Unit = {
|
||||
if(iter.hasNext) {
|
||||
val recipient = iter.next
|
||||
if(recipient.sendTo != ActorRef.noSender) {
|
||||
recipient.sendTo ! RenderOrderRemainderMsg(position)
|
||||
}
|
||||
recursiveOrderReminder(iter, position + 1)
|
||||
}
|
||||
def DisposeSpawnedVehicle(vehicle : Vehicle, zone: Zone) : Unit = {
|
||||
zone.VehicleEvents ! VehicleSpawnPad.DisposeVehicle(vehicle)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,26 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import net.psforever.objects.serverobject.pad.process.AutoDriveControls
|
||||
import net.psforever.objects.{Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
/**
|
||||
* A structure-owned server object that is a "spawn pad" for vehicles.<br>
|
||||
* <br>
|
||||
* Spawn pads have no purpose on their own but
|
||||
* maintain the operative queue that introduces the vehicle into the game world and applies initial activity to it and
|
||||
* maintain a position and a direction where the vehicle will be made to appear (as a `PlanetSideServerObject`).
|
||||
* The actual functionality managed by this object is wholly found on its accompanying `Actor`.
|
||||
* Spawn pads have no purpose on their own, save to represent the position and orientation of the game object.
|
||||
* Their control `Actor` object maintains the operative queue by which a vehicle is introduced into the game world.
|
||||
* The common features of spawn pads are its horizontal doors.
|
||||
* Most spawn pads also contain a lifting platform that hoists the vehicles out a concealed trench.
|
||||
* The Battleframe Robotics spawn sheds do not have lifting platforms as they are vertical structures.
|
||||
* @see `VehicleSpawnControl`
|
||||
* @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class VehicleSpawnPad(spDef : VehicleSpawnPadDefinition) extends Amenity {
|
||||
/**
|
||||
* Use the in-game railed platform to lift the spawned vehicle out of the trench.
|
||||
* When set, the client performs the standard vehicle entry procedure, including lifting platform animations.
|
||||
* When unset, the client depicts the player manually boarding the new vehicle within the trench area.
|
||||
* Eventually, the vehicle is then hoisted out into the open; without this set, that hoisting is abrupt.
|
||||
* The main reason to disable this feature is to avoid an `ObjectAttachMessage` for an incorrect object designation.
|
||||
* Unset if not guaranteed to have the correct globally unique id of the spawn pad.
|
||||
*/
|
||||
private var onRails : Boolean = true
|
||||
|
||||
private var guidedPath : List[AutoDriveControls.Configuration] = Nil
|
||||
|
||||
def Railed : Boolean = onRails
|
||||
|
||||
def Railed_=(useRails : Boolean) : Boolean = {
|
||||
onRails = useRails
|
||||
Railed
|
||||
}
|
||||
|
||||
def Guide : List[AutoDriveControls.Configuration] = guidedPath
|
||||
|
||||
def Guide_=(path : List[AutoDriveControls.Configuration]) : List[AutoDriveControls.Configuration] = {
|
||||
guidedPath = path
|
||||
Guide
|
||||
}
|
||||
|
||||
def Definition : VehicleSpawnPadDefinition = spDef
|
||||
}
|
||||
|
||||
object VehicleSpawnPad {
|
||||
|
||||
/**
|
||||
* Message to the spawn pad to enqueue the following vehicle order.
|
||||
* This is the entry point to vehicle spawn pad functionality.
|
||||
|
|
@ -61,24 +33,21 @@ object VehicleSpawnPad {
|
|||
* Message to indicate that a certain player should be made transparent.
|
||||
* @see `GenericObjectActionMessage`
|
||||
* @param player_guid the player
|
||||
* @param zone_id the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID, zone_id : String)
|
||||
final case class ConcealPlayer(player_guid: PlanetSideGUID)
|
||||
|
||||
/**
|
||||
* Message is intended to undo the effects of the above message, `ConcealPlayer`.
|
||||
* @see `ConcealPlayer`
|
||||
* @param player_guid the player
|
||||
* @param zone_id the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class RevealPlayer(player_guid : PlanetSideGUID, zone_id : String)
|
||||
final case class RevealPlayer(player_guid: PlanetSideGUID)
|
||||
|
||||
/**
|
||||
* Message to properly introduce the vehicle into the zone.
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param zone the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class LoadVehicle(vehicle : Vehicle, zone : Zone)
|
||||
final case class LoadVehicle(vehicle: Vehicle)
|
||||
|
||||
/**
|
||||
* Message to attach the vehicle to the spawn pad's lifting platform ("put on rails").
|
||||
|
|
@ -86,76 +55,77 @@ object VehicleSpawnPad {
|
|||
* @see `ObjectAttachMessage`
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
* @param zone_id the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class AttachToRails(vehicle : Vehicle, pad : VehicleSpawnPad, zone_id : String)
|
||||
final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message to detach the vehicle from the spawn pad's lifting platform ("put on rails").
|
||||
* @see `ObjectDetachMessage`
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
* @param zone_id the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class DetachFromRails(vehicle : Vehicle, pad : VehicleSpawnPad, zone_id : String)
|
||||
final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message that resets the spawn pad for its next order fulfillment operation by lowering the lifting platform.
|
||||
* @see `GenericObjectActionMessage`
|
||||
* @param pad the spawn pad
|
||||
* @param zone_id the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class ResetSpawnPad(pad : VehicleSpawnPad, zone_id : String)
|
||||
final case class ResetSpawnPad(pad: VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message that acts as callback to the driver that the process of sitting in the driver seat will be initiated soon.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class StartPlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
final case class StartPlayerSeatedInVehicle(driver_name : String, vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message that acts as callback to the driver that the process of sitting in the driver seat should be finished.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class PlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad) //TODO while using fake rails
|
||||
final case class PlayerSeatedInVehicle(driver_name : String, vehicle : Vehicle, pad : VehicleSpawnPad) //TODO while using fake rails
|
||||
|
||||
/**
|
||||
* Message that starts the newly-spawned vehicle to begin driving away from the spawn pad.
|
||||
* Information about the driving process is available on the vehicle itself.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @see `VehicleDefinition`
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class ServerVehicleOverrideStart(vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
final case class ServerVehicleOverrideStart(driver_name : String, vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message that transitions the newly-spawned vehicle into a cancellable auto-drive state.
|
||||
* Information about the driving process is available on the vehicle itself.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @see `VehicleDefinition`
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class ServerVehicleOverrideEnd(vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
final case class ServerVehicleOverrideEnd(driver_name : String, vehicle : Vehicle, pad : VehicleSpawnPad)
|
||||
|
||||
/**
|
||||
* Message to initiate the process of properly disposing of the vehicle that may have been or was spawned into the game world.
|
||||
* @param vehicle the vehicle
|
||||
* @param zone the zone in which the spawn pad is located
|
||||
*/
|
||||
final case class DisposeVehicle(vehicle : Vehicle, zone : Zone)
|
||||
final case class DisposeVehicle(vehicle: Vehicle)
|
||||
|
||||
/**
|
||||
* Message to send targeted messages to the clients of specific users.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param reason the nature of the message
|
||||
* @param data optional information for rendering the message to the client
|
||||
*/
|
||||
final case class PeriodicReminder(reason : Reminders.Value, data : Option[Any] = None)
|
||||
final case class PeriodicReminder(driver_name : String, reason : Reminders.Value, data : Option[Any] = None)
|
||||
|
||||
/**
|
||||
* An `Enumeration` of reasons for sending a periodic reminder to the user.
|
||||
|
|
@ -179,7 +149,6 @@ object VehicleSpawnPad {
|
|||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
/**
|
||||
* Instantiate and configure a `VehicleSpawnPad` object
|
||||
* @param pdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
|
|
@ -191,7 +160,6 @@ object VehicleSpawnPad {
|
|||
*/
|
||||
def Constructor(pos : Vector3, pdef: VehicleSpawnPadDefinition, orient : Vector3)(id : Int, context : ActorContext) : VehicleSpawnPad = {
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
|
||||
val obj = VehicleSpawnPad(pdef)
|
||||
obj.Position = pos
|
||||
|
|
|
|||
|
|
@ -1,304 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
/**
|
||||
* Instructions to be processed by `VehicleSpawnControlGuided`.
|
||||
* These instructions coordinate basic vehicle manipulations such as driving, turning, and stopping.
|
||||
* If defined, they will operate on a newly formed vehicle after it is released from its spawn pad lifting platform
|
||||
* and after it has been issued at least one `ServerVehicleOverrideMsg` packet.
|
||||
*/
|
||||
object AutoDriveControls {
|
||||
|
||||
/**
|
||||
* A container that translates to a new `Setting` instruction.
|
||||
* Instructions are maintained in this form until they will be used due to the nature of the `Setting` object.
|
||||
* The least that this object needs to do is accept parameters that matches the specific `Setting` that it outputs.
|
||||
*/
|
||||
sealed trait Configuration {
|
||||
def Create : Setting
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction to be consumed by the cyclic operation of `VehicleSpawnControlGuided`
|
||||
* and are created by a `Configuration` object.
|
||||
* They are considered semi-immutable `case class` objects.
|
||||
* Externally, they are immutable by proper Scala standards.
|
||||
* Internally, they will be permitted `private` fields that can be modified the first time the object is used.
|
||||
*/
|
||||
sealed trait Setting {
|
||||
/**
|
||||
* The nature of the action being performed.
|
||||
* @return an enumerated value that explains the purpose of the action
|
||||
*/
|
||||
def Type : State.Value
|
||||
/**
|
||||
* The delay in between checks to determine if this setting has accomplished its goal or has entered an invalid state.
|
||||
* @return the length of the delay
|
||||
*/
|
||||
def Delay : Long = 200L
|
||||
/**
|
||||
* Data that is important for fulfilling the instruction on a user's client.
|
||||
* Highly specific to the implementation.
|
||||
* @return any data deemed important; `None`, if unnecessary
|
||||
*/
|
||||
def Data : Option[Any] = None
|
||||
/**
|
||||
* Perform a test to determine if the vehicle is capable of performing the action this instruction requires.
|
||||
* The test is typically simplistic in nature and often boils down to whether o not the vehicle is mobile.
|
||||
* @param vehicle the vehicle being controlled
|
||||
* @return `true`, if the action can (probably) be accomplished under the current conditions; `false`, otherwise
|
||||
*/
|
||||
def Validate(vehicle : Vehicle) : Boolean = vehicle.isMoving
|
||||
/**
|
||||
* Perform a test to determine if the vehicle has reached a set of conditions
|
||||
* where the action performed by the instruction has been fulfilled.
|
||||
* This should count as the "end of this step" and the "beginning of the next step."
|
||||
* @param vehicle the vehicle being controlled
|
||||
* @return `true`, if the action has run to completion; `false`, otherwise
|
||||
*/
|
||||
def CompletionTest(vehicle : Vehicle) : Boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* The nature of the action being performed.
|
||||
* Different actions can be divided into types.
|
||||
*/
|
||||
object State extends Enumeration {
|
||||
val
|
||||
Cancel,
|
||||
Climb,
|
||||
Drive,
|
||||
Stop,
|
||||
Turn,
|
||||
Wait
|
||||
= Value
|
||||
}
|
||||
|
||||
protected final case class AutoDrive(speed : Int) extends Setting {
|
||||
def Type = State.Drive
|
||||
|
||||
override def Data = Some(speed)
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = true
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = vehicle.isMoving
|
||||
}
|
||||
|
||||
protected final case class AutoDriveDistance(start : Vector3, sqDistance : Float) extends Setting {
|
||||
def Type = State.Wait
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) : Boolean = {
|
||||
Vector3.DistanceSquared(vehicle.Position.xy, start) > sqDistance
|
||||
}
|
||||
}
|
||||
|
||||
protected final case class AutoDriveDistanceFromHere(sqDistance : Float) extends Setting {
|
||||
private var start : Option[Vector3] = None
|
||||
|
||||
def Type = State.Wait
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) : Boolean = {
|
||||
val startLoc = start.getOrElse({
|
||||
start = Some(vehicle.Position.xy)
|
||||
start.get
|
||||
})
|
||||
Vector3.DistanceSquared(vehicle.Position.xy, startLoc) > sqDistance
|
||||
}
|
||||
}
|
||||
|
||||
protected final case class AutoDriveForTime(length : Long) extends Setting {
|
||||
private var start : Option[Long] = None
|
||||
|
||||
def Type = State.Wait
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) : Boolean = {
|
||||
val time : Long = System.currentTimeMillis
|
||||
val startTime = start.getOrElse({
|
||||
start = Some(time)
|
||||
time
|
||||
})
|
||||
time - startTime >= length
|
||||
}
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = true
|
||||
}
|
||||
|
||||
protected final case class AutoDriveTurnBy(angle : Float, direction : Int) extends Setting {
|
||||
private var end : Option[Float] = None
|
||||
private var currAng : Float = 0f
|
||||
|
||||
def Type = State.Turn
|
||||
|
||||
override def Delay : Long = 100L //increased frequency
|
||||
|
||||
override def Data = Some(direction)
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) : Boolean = {
|
||||
val endAng = end.getOrElse {
|
||||
currAng = vehicle.Orientation.z
|
||||
var ang = (currAng + angle) % 360f
|
||||
if(ang < 0f) {
|
||||
ang += 360f
|
||||
}
|
||||
end = Some(ang)
|
||||
ang
|
||||
}
|
||||
val lastAng = currAng
|
||||
currAng = vehicle.Orientation.z
|
||||
//check that the expected angle is sandwiched between the previous angle and the current angle
|
||||
currAng == endAng || (lastAng < endAng && endAng <= currAng) || (lastAng > endAng && endAng >= currAng)
|
||||
}
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = direction != 15 && super.Validate(vehicle)
|
||||
}
|
||||
|
||||
protected final case class AutoDriveFirstGear() extends Setting {
|
||||
private var speed : Int = 0
|
||||
|
||||
def Type = State.Drive
|
||||
|
||||
override def Data = Some(speed)
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = vehicle.isMoving
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = {
|
||||
speed = vehicle.Definition.AutoPilotSpeed1
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
protected final case class AutoDriveSecondGear() extends Setting {
|
||||
private var speed : Int = 0
|
||||
|
||||
def Type = State.Drive
|
||||
|
||||
override def Data = Some(speed)
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = vehicle.isMoving
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = {
|
||||
speed = vehicle.Definition.AutoPilotSpeed2
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
protected final case class AutoDriveClimb(altitude : Float) extends Setting {
|
||||
def Type = State.Climb
|
||||
|
||||
override def Data = Some(altitude)
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = {
|
||||
vehicle.Position.z >= altitude
|
||||
}
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = GlobalDefinitions.isFlightVehicle(vehicle.Definition)
|
||||
}
|
||||
|
||||
protected final case class AutoDriveCancelEarly(test : (Vehicle) => Boolean) extends Setting {
|
||||
def Type = State.Cancel
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = true
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = test(vehicle)
|
||||
}
|
||||
|
||||
protected final case class AutoDriveStop() extends Setting {
|
||||
def Type = State.Stop
|
||||
|
||||
override def Validate(vehicle : Vehicle) : Boolean = true
|
||||
|
||||
def CompletionTest(vehicle : Vehicle) = Validate(vehicle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a validation test to determine if the remainder of the instructions should be processed.
|
||||
* @param test the custom valid conditions of the vehicle for continuing
|
||||
*/
|
||||
final case class CancelEarly(test : (Vehicle)=>Boolean) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveCancelEarly(test)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gain altitude with a flying vehicle.
|
||||
* The climb speed is fixed.
|
||||
* @param altitude the vertical distance to ascend
|
||||
*/
|
||||
final case class Climb(altitude : Float) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveClimb(altitude)
|
||||
}
|
||||
|
||||
/**
|
||||
* Drive a certain distance from somewhere.
|
||||
* @param start the fixed coordinates of the origin point
|
||||
* @param distance how far from the origin point the vehicle should travel
|
||||
*/
|
||||
final case class Distance(start : Vector3, distance : Float) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveDistance(start, distance * distance)
|
||||
}
|
||||
|
||||
/**
|
||||
* Drive a certain distance from where the vehicle is at the time that the instruction is called.
|
||||
* The starting position is the current position of the vehicle.
|
||||
* @param distance how far from the origin point the vehicle should travel
|
||||
*/
|
||||
final case class DistanceFromHere(distance : Float) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveDistanceFromHere(distance * distance)
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic drive forward instruction.
|
||||
* @see `ServerVehicleOverrideMsg.forward_speed`
|
||||
* @param speed the speed that the vehicle accelerates to;
|
||||
* scaled in a curious way
|
||||
*/
|
||||
final case class Drive(speed : Int) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDrive(speed)
|
||||
}
|
||||
|
||||
/**
|
||||
* Special drive forward instruction.
|
||||
* @see `ServerVehicleOverrideMsg.forward_speed`
|
||||
* @see `VehicleDefinition.AutoPilotSpeed1`
|
||||
*/
|
||||
final case class FirstGear() extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveFirstGear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Drive or idle for a certain duration.
|
||||
* The starting position is the current position of the vehicle.
|
||||
* @param time how long to contiue driving under the current conditions
|
||||
*/
|
||||
final case class ForTime(time : Long) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveForTime(time)
|
||||
}
|
||||
|
||||
/**
|
||||
* Special drive forward instruction.
|
||||
* @see `ServerVehicleOverrideMsg.forward_speed`
|
||||
* @see `VehicleDefinition.AutoPilotSpeed2`
|
||||
*/
|
||||
final case class SecondGear() extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveSecondGear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop driving (but do not cancel the server override state).
|
||||
*/
|
||||
final case class Stop() extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveStop()
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the vehicle to turn a certain amount.
|
||||
* @see `VehicleMessage.wheel_direction`
|
||||
* @param angle the angle by which to turn the vehicle
|
||||
* @param direction the wheel direction of the vehicle
|
||||
*/
|
||||
final case class TurnBy(angle : Float, direction : Int) extends Configuration {
|
||||
def Create : Setting = AutoDriveControls.AutoDriveTurnBy(angle, direction)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package net.psforever.objects.serverobject.pad.process
|
|||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.zones.Zone
|
||||
import org.log4s.Logger
|
||||
|
||||
|
|
@ -26,11 +25,11 @@ abstract class VehicleSpawnControlBase(pad : VehicleSpawnPad) extends Actor {
|
|||
*/
|
||||
private def GetLogger(logid : String) : Logger = baseLogger match {
|
||||
case None =>
|
||||
if(!pad.HasGUID || Continent == Zone.Nowhere) {
|
||||
if(!pad.HasGUID || pad.Owner.Zone == Zone.Nowhere) {
|
||||
org.log4s.getLogger(s"uninitialized_${pad.Definition.Name}$logid")
|
||||
}
|
||||
else {
|
||||
baseLogger = Some(org.log4s.getLogger(s"${Continent.Id}-${pad.Definition.Name}-${pad.GUID.guid}$logid"))
|
||||
baseLogger = Some(org.log4s.getLogger(s"${pad.Continent}-${pad.Definition.Name}-${pad.GUID.guid}$logid"))
|
||||
baseLogger.get
|
||||
}
|
||||
case Some(logger) =>
|
||||
|
|
@ -56,14 +55,4 @@ abstract class VehicleSpawnControlBase(pad : VehicleSpawnPad) extends Actor {
|
|||
* @param msg the message
|
||||
*/
|
||||
def trace(msg : String) : Unit = log.trace(msg)
|
||||
|
||||
/**
|
||||
* The continent the pad recognizes as a place of installation will change as its `Owner` changes.
|
||||
* Originally, it belongs to a default non-`Building` object that is owned by a default non-`Zone` object.
|
||||
* Eventually, it will belong to an active `Building` object that will belong to an active `Zone` object.
|
||||
* With respect to `GetLogger(String)`, the active `Zone` object will be valid shortly after the object is registered,
|
||||
* but will still be separated from being owned by a valid `Building` object by a few validation checks.
|
||||
* @return the (current) `Zone` object
|
||||
*/
|
||||
def Continent : Zone = pad.Owner.asInstanceOf[Building].Zone
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
|
@ -24,17 +24,16 @@ class VehicleSpawnControlConcealPlayer(pad : VehicleSpawnPad) extends VehicleSpa
|
|||
val loadVehicle = context.actorOf(Props(classOf[VehicleSpawnControlLoadVehicle], pad), s"${context.parent.path.name}-load")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.ConcealPlayer(entry) =>
|
||||
val driver = entry.driver
|
||||
//TODO how far can the driver get stray from the Terminal before his order is cancelled?
|
||||
if(entry.sendTo != ActorRef.noSender && driver.Continent == Continent.Id && driver.VehicleSeated.isEmpty) {
|
||||
case order @ VehicleSpawnControl.Order(driver, _) =>
|
||||
//TODO how far can the driver stray from the Terminal before his order is cancelled?
|
||||
if(driver.Continent == pad.Continent && driver.VehicleSeated.isEmpty) {
|
||||
trace(s"hiding ${driver.Name}")
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID, Continent.Id)
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, VehicleSpawnControl.Process.LoadVehicle(entry))
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID)
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order)
|
||||
}
|
||||
else {
|
||||
trace(s"integral component lost; abort order fulfillment")
|
||||
VehicleSpawnControl.DisposeVehicle(entry, Continent)
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(order.vehicle, pad.Owner.Zone)
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
|
||||
/**
|
||||
|
|
@ -20,35 +20,22 @@ class VehicleSpawnControlDriverControl(pad : VehicleSpawnPad) extends VehicleSpa
|
|||
val finalClear = context.actorOf(Props(classOf[VehicleSpawnControlFinalClearance], pad), s"${context.parent.path.name}-final")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.DriverVehicleControl(entry) =>
|
||||
val vehicle = entry.vehicle
|
||||
if(pad.Railed) {
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad, Continent.Id)
|
||||
}
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
if(vehicle.Health == 0) {
|
||||
trace(s"vehicle was already destroyed; but, everything is fine")
|
||||
}
|
||||
if(entry.sendTo != ActorRef.noSender) {
|
||||
val driver = entry.driver
|
||||
entry.sendTo ! VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad)
|
||||
if(driver.VehicleSeated.contains(vehicle.GUID)) {
|
||||
trace(s"returning control of ${vehicle.Definition.Name} to ${driver.Name}")
|
||||
}
|
||||
else {
|
||||
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; vehicle controls have been locked")
|
||||
}
|
||||
if(vehicle.PassengerInSeat(driver).contains(0)) {
|
||||
trace(s"returning control of ${vehicle.Definition.Name} to ${driver.Name}")
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideEnd(driver.Name, vehicle, pad)
|
||||
}
|
||||
else {
|
||||
trace("can not properly return control to driver")
|
||||
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; vehicle controls have been locked")
|
||||
}
|
||||
finalClear ! VehicleSpawnControl.Process.FinalClearance(entry)
|
||||
finalClear ! order
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
context.parent ! msg
|
||||
|
||||
case msg @ VehicleSpawnControl.Process.FinalClearance(_) =>
|
||||
finalClear ! msg
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.Vector3
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -22,17 +24,24 @@ class VehicleSpawnControlFinalClearance(pad : VehicleSpawnPad) extends VehicleSp
|
|||
def LogId = "-clearer"
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.FinalClearance(entry) =>
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
if(vehicle.PassengerInSeat(driver).isEmpty) {
|
||||
//ensure the vacant vehicle is above the trench and doors
|
||||
vehicle.Position = pad.Position + Vector3.z(pad.Definition.VehicleCreationZOffset)
|
||||
val definition = vehicle.Definition
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleServiceMessage(s"${pad.Continent}", VehicleAction.LoadVehicle(PlanetSideGUID(0), vehicle, definition.ObjectId, vehicle.GUID, definition.Packet.ConstructorData(vehicle).get))
|
||||
}
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.Reminder
|
||||
self ! VehicleSpawnControlFinalClearance.Test(entry)
|
||||
self ! VehicleSpawnControlFinalClearance.Test(order)
|
||||
|
||||
case VehicleSpawnControlFinalClearance.Test(entry) =>
|
||||
case test @ VehicleSpawnControlFinalClearance.Test(entry) =>
|
||||
if(Vector3.DistanceSquared(entry.vehicle.Position, pad.Position) > 100.0f) { //10m away from pad
|
||||
trace("pad cleared")
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad)
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
|
||||
}
|
||||
else {
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, self, VehicleSpawnControlFinalClearance.Test(entry))
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, self, test)
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad`.
|
||||
* The basic `VehicleSpawnControl` is the root of a simple tree of "spawn control" objects that chain to each other.
|
||||
* Each object performs on (or more than one related) actions upon the vehicle order that was submitted.<br>
|
||||
* <br>
|
||||
* After the vehicle has been released from the spawn pad lifting platform,
|
||||
* it enters into an auto-drive mode that has at least two stages.
|
||||
* An undefined number of stages cane be included, however.
|
||||
* This can lead the newly-spawned vehicle through a rough pre-defined path.<br>
|
||||
* <br>
|
||||
* Throughout this process, the conditions of `ServerVehicleOverrideMsg` are still in effect.
|
||||
* @param pad the `VehicleSpawnPad` object being governed
|
||||
*/
|
||||
class VehicleSpawnControlGuided(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) {
|
||||
def LogId = "-guide"
|
||||
|
||||
val driverControl = context.actorOf(Props(classOf[VehicleSpawnControlDriverControl], pad), s"${context.parent.path.name}-driver")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.StartGuided(entry) =>
|
||||
pad.Guide match {
|
||||
case Nil =>
|
||||
trace("no guided path for this pad")
|
||||
driverControl ! VehicleSpawnControl.Process.DriverVehicleControl(entry)
|
||||
case path =>
|
||||
self ! VehicleSpawnControlGuided.InitialGuided(entry, path.map { _.Create })
|
||||
}
|
||||
|
||||
case VehicleSpawnControlGuided.SelectNextGuided(entry, actions) =>
|
||||
actions match {
|
||||
case Nil | _ :: Nil =>
|
||||
trace("custom vehicle path completed")
|
||||
driverControl ! VehicleSpawnControl.Process.DriverVehicleControl(entry)
|
||||
case _ :: xs =>
|
||||
self ! VehicleSpawnControlGuided.InitialGuided(entry, xs)
|
||||
}
|
||||
|
||||
case VehicleSpawnControlGuided.InitialGuided(entry, actions) =>
|
||||
val vehicle = entry.vehicle
|
||||
if(entry.sendTo != ActorRef.noSender && vehicle.Health != 0 && entry.driver.VehicleSeated.contains(vehicle.GUID) && actions.head.Validate(vehicle)) {
|
||||
trace(s"custom vehicle path plotted - ${actions.head.Type}")
|
||||
entry.sendTo ! VehicleSpawnControlGuided.GuidedControl(actions.head.Type, vehicle, actions.head.Data)
|
||||
self ! VehicleSpawnControlGuided.ContinueGuided(entry, actions)
|
||||
}
|
||||
else {
|
||||
trace(s"projected ${vehicle.Definition.Name} path interruption; exit guided mode")
|
||||
driverControl ! VehicleSpawnControl.Process.DriverVehicleControl(entry)
|
||||
}
|
||||
|
||||
case VehicleSpawnControlGuided.ValidateGuided(entry, actions) =>
|
||||
val vehicle = entry.vehicle
|
||||
if(entry.sendTo != ActorRef.noSender && vehicle.Health != 0 && entry.driver.VehicleSeated.contains(vehicle.GUID) && actions.head.Validate(vehicle)) {
|
||||
self ! VehicleSpawnControlGuided.ContinueGuided(entry, actions)
|
||||
}
|
||||
else {
|
||||
trace(s"plotted ${vehicle.Definition.Name} path interruption; exit guided mode")
|
||||
driverControl ! VehicleSpawnControl.Process.DriverVehicleControl(entry)
|
||||
}
|
||||
|
||||
case VehicleSpawnControlGuided.ContinueGuided(entry, actions) =>
|
||||
if(actions.head.CompletionTest(entry.vehicle)) {
|
||||
trace("step completed")
|
||||
self ! VehicleSpawnControlGuided.SelectNextGuided(entry, actions)
|
||||
}
|
||||
else {
|
||||
context.system.scheduler.scheduleOnce(actions.head.Delay milliseconds, self, VehicleSpawnControlGuided.ValidateGuided(entry, actions))
|
||||
}
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
context.parent ! msg
|
||||
|
||||
case msg @ VehicleSpawnControl.Process.FinalClearance(_) =>
|
||||
driverControl ! msg
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
object VehicleSpawnControlGuided {
|
||||
/**
|
||||
* Select the first instruction from the list.
|
||||
* @param entry the vehicle order
|
||||
* @param actions the list of instructions related to this spawn pad
|
||||
*/
|
||||
private final case class InitialGuided(entry : VehicleSpawnControl.Order, actions : List[AutoDriveControls.Setting])
|
||||
/**
|
||||
* Swap to the next instruction, if it exists.
|
||||
* @param entry the vehicle order
|
||||
* @param actions the list of instructions related to this spawn pad
|
||||
*/
|
||||
private final case class SelectNextGuided(entry : VehicleSpawnControl.Order, actions : List[AutoDriveControls.Setting])
|
||||
/**
|
||||
* The validation test determines whether the vehicle, the driver, and any other important elements
|
||||
* are still in a state where the current instruction can be accomplished.
|
||||
* If the validation test passes, the current instruction can continue to run to completion.
|
||||
* If the validation test fails, the remainder of the instructions are aborted.
|
||||
* @param entry the vehicle order
|
||||
* @param actions the list of instructions related to this spawn pad
|
||||
*/
|
||||
private final case class ValidateGuided(entry : VehicleSpawnControl.Order, actions : List[AutoDriveControls.Setting])
|
||||
/**
|
||||
* If the previous validation test passes, the current instruction can continue to run to completion.
|
||||
* Once completed, the next instruction can be selected.
|
||||
* @param entry the vehicle order
|
||||
* @param actions the list of instructions related to this spawn pad
|
||||
*/
|
||||
private final case class ContinueGuided(entry : VehicleSpawnControl.Order, actions : List[AutoDriveControls.Setting])
|
||||
|
||||
/**
|
||||
* A message that explains the current instruction in the guided mode to another agency.
|
||||
* @param command the nature of the action being performed
|
||||
* @param vehicle the vehicle being controlled
|
||||
* @param data optional data used to process the instruction
|
||||
*/
|
||||
final case class GuidedControl(command : AutoDriveControls.State.Value, vehicle : Vehicle, data : Option[Any])
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ import scala.concurrent.duration._
|
|||
* Each object performs on (or more than one related) actions upon the vehicle order that was submitted.<br>
|
||||
* <br>
|
||||
* This object introduces the vehicle into the game environment.
|
||||
* The vehicle must be added to the `Continent`, loaded onto other players' clients, and given an initial timed deconstruction event.
|
||||
* For actual details on this process, please refer to the external source represented by `Continent.VehicleEvents`.
|
||||
* The vehicle must be added to the `Zone` object, loaded onto other players' clients, and given an initial timed deconstruction event.
|
||||
* For actual details on this process, please refer to the external source represented by `pad.Owner.Zone.VehicleEvents`.
|
||||
* It has failure cases should the driver be in an incorrect state.
|
||||
* @param pad the `VehicleSpawnPad` object being governed
|
||||
*/
|
||||
|
|
@ -26,21 +26,17 @@ class VehicleSpawnControlLoadVehicle(pad : VehicleSpawnPad) extends VehicleSpawn
|
|||
val railJack = context.actorOf(Props(classOf[VehicleSpawnControlRailJack], pad), s"${context.parent.path.name}-rails")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.LoadVehicle(entry) =>
|
||||
val vehicle = entry.vehicle
|
||||
if(entry.driver.Continent == Continent.Id) {
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
if(driver.Continent == pad.Continent && vehicle.Health > 0) {
|
||||
trace(s"loading the ${vehicle.Definition.Name}")
|
||||
if(pad.Railed) {
|
||||
//load the vehicle in the spawn pad trench, underground, initially
|
||||
vehicle.Position = vehicle.Position - Vector3(0, 0, if(GlobalDefinitions.isFlightVehicle(vehicle.Definition)) 9 else 5)
|
||||
}
|
||||
vehicle.Cloaked = vehicle.Definition.CanCloak && entry.driver.Cloaked
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.LoadVehicle(vehicle, Continent)
|
||||
context.system.scheduler.scheduleOnce(100 milliseconds, railJack, VehicleSpawnControl.Process.RailJackAction(entry))
|
||||
vehicle.Position = vehicle.Position - Vector3.z(if(GlobalDefinitions.isFlightVehicle(vehicle.Definition)) 9 else 5) //appear below the trench and doors
|
||||
vehicle.Cloaked = vehicle.Definition.CanCloak && driver.Cloaked
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.LoadVehicle(vehicle)
|
||||
context.system.scheduler.scheduleOnce(100 milliseconds, railJack, order)
|
||||
}
|
||||
else {
|
||||
trace("owner lost; abort order fulfillment")
|
||||
VehicleSpawnControl.DisposeVehicle(entry, Continent)
|
||||
trace("owner lost or vehicle in poor condition; abort order fulfillment")
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(order, pad.Owner.Zone)
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,15 +25,9 @@ class VehicleSpawnControlRailJack(pad : VehicleSpawnPad) extends VehicleSpawnCon
|
|||
val seatDriver = context.actorOf(Props(classOf[VehicleSpawnControlSeatDriver], pad), s"${context.parent.path.name}-seat")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.RailJackAction(entry) =>
|
||||
if(pad.Railed) {
|
||||
trace(s"attaching vehicle to railed platform")
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.AttachToRails(entry.vehicle, pad, Continent.Id)
|
||||
}
|
||||
else {
|
||||
trace(s"railed platform skipped; vehicle positioned in pad trench temporarily")
|
||||
}
|
||||
context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, VehicleSpawnControl.Process.SeatDriver(entry))
|
||||
case order @ VehicleSpawnControl.Order(_, vehicle) =>
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad)
|
||||
context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order)
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
context.parent ! msg
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -29,62 +27,35 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
|
|||
val vehicleOverride = context.actorOf(Props(classOf[VehicleSpawnControlServerVehicleOverride], pad), s"${context.parent.path.name}-override")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.SeatDriver(entry) =>
|
||||
self ! VehicleSpawnControlSeatDriver.AwaitVehicleReadiness(entry)
|
||||
|
||||
case VehicleSpawnControlSeatDriver.AwaitVehicleReadiness(entry) =>
|
||||
if(entry.vehicle.Actor == ActorRef.noSender) { //wait for a necessary vehicle component to be loaded
|
||||
context.system.scheduler.scheduleOnce(50 milliseconds, self, VehicleSpawnControlSeatDriver.AwaitVehicleReadiness(entry))
|
||||
case order @ VehicleSpawnControl.Order(_, vehicle) =>
|
||||
if(vehicle.Actor == ActorRef.noSender) { //wait for a necessary vehicle component to be loaded
|
||||
context.system.scheduler.scheduleOnce(50 milliseconds, self, order)
|
||||
}
|
||||
else {
|
||||
trace("vehicle ready")
|
||||
self ! VehicleSpawnControlSeatDriver.BeginDriverInSeat(entry)
|
||||
self ! VehicleSpawnControlSeatDriver.BeginDriverInSeat(order)
|
||||
}
|
||||
|
||||
case VehicleSpawnControlSeatDriver.BeginDriverInSeat(entry) =>
|
||||
val driver = entry.driver
|
||||
if(entry.sendTo != ActorRef.noSender && entry.vehicle.Health > 0 && driver.isAlive && driver.Continent == Continent.Id && driver.VehicleSeated.isEmpty) {
|
||||
if(entry.vehicle.Health > 0 && driver.isAlive && driver.Continent == pad.Continent && driver.VehicleSeated.isEmpty) {
|
||||
trace("driver to be made seated in vehicle")
|
||||
entry.sendTo ! VehicleSpawnPad.StartPlayerSeatedInVehicle(entry.vehicle, pad)
|
||||
entry.vehicle.Actor.tell(Mountable.TryMount(driver, 0), entry.sendTo) //entry.sendTo should handle replies to TryMount
|
||||
context.system.scheduler.scheduleOnce(1500 milliseconds, self, VehicleSpawnControlSeatDriver.AwaitDriverInSeat(entry))
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.StartPlayerSeatedInVehicle(entry.driver.Name, entry.vehicle, pad)
|
||||
}
|
||||
else {
|
||||
else{
|
||||
trace("driver lost; vehicle stranded on pad")
|
||||
context.system.scheduler.scheduleOnce(1000 milliseconds, vehicleOverride, VehicleSpawnControl.Process.ServerVehicleOverride(entry))
|
||||
}
|
||||
|
||||
case VehicleSpawnControlSeatDriver.AwaitDriverInSeat(entry) =>
|
||||
val driver = entry.driver
|
||||
if(entry.sendTo == ActorRef.noSender || !driver.isAlive || driver.Continent != Continent.Id) {
|
||||
trace("driver lost, but operations can continue")
|
||||
vehicleOverride ! VehicleSpawnControl.Process.ServerVehicleOverride(entry)
|
||||
}
|
||||
else if(entry.vehicle.Health == 0 || entry.vehicle.Position == Vector3.Zero) {
|
||||
//skip ahead for cleanup
|
||||
vehicleOverride ! VehicleSpawnControl.Process.ServerVehicleOverride(entry)
|
||||
}
|
||||
else if(driver.isAlive && driver.VehicleSeated.isEmpty) {
|
||||
if(pad.Railed) {
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.DetachFromRails(entry.vehicle, pad, Continent.Id)
|
||||
}
|
||||
context.system.scheduler.scheduleOnce(100 milliseconds, self, VehicleSpawnControlSeatDriver.AwaitDriverInSeat(entry))
|
||||
}
|
||||
else {
|
||||
trace(s"driver is sitting down")
|
||||
val time = if(pad.Railed) 1000 else VehicleSpawnControlSeatDriver.RaillessSeatAnimationTimes(entry.vehicle.Definition.Name)
|
||||
context.system.scheduler.scheduleOnce(time milliseconds, self, VehicleSpawnControlSeatDriver.DriverInSeat(entry))
|
||||
}
|
||||
context.system.scheduler.scheduleOnce(2500 milliseconds, self, VehicleSpawnControlSeatDriver.DriverInSeat(entry))
|
||||
|
||||
case VehicleSpawnControlSeatDriver.DriverInSeat(entry) =>
|
||||
if(entry.sendTo != ActorRef.noSender || entry.driver.Continent != Continent.Id) {
|
||||
if(entry.driver.isAlive && entry.vehicle.PassengerInSeat(entry.driver).contains(0)) {
|
||||
trace(s"driver ${entry.driver.Name} has taken the wheel")
|
||||
entry.sendTo ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad)
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.driver.Name, entry.vehicle, pad)
|
||||
}
|
||||
else {
|
||||
trace("driver lost, but operations can continue")
|
||||
}
|
||||
context.system.scheduler.scheduleOnce(250 milliseconds, vehicleOverride, VehicleSpawnControl.Process.ServerVehicleOverride(entry))
|
||||
context.system.scheduler.scheduleOnce(250 milliseconds, vehicleOverride, entry)
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
context.parent ! msg
|
||||
|
|
@ -94,51 +65,7 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
|
|||
}
|
||||
|
||||
object VehicleSpawnControlSeatDriver {
|
||||
final case class AwaitVehicleReadiness(entry : VehicleSpawnControl.Order)
|
||||
|
||||
final case class BeginDriverInSeat(entry : VehicleSpawnControl.Order)
|
||||
|
||||
final case class AwaitDriverInSeat(entry : VehicleSpawnControl.Order)
|
||||
|
||||
final case class DriverInSeat(entry : VehicleSpawnControl.Order)
|
||||
|
||||
/**
|
||||
* If the spawn pad associated with this `Actor` chain is not `Railed` -
|
||||
* not guaranteed to have the correct ingame globally unique id of the spawn pad -
|
||||
* then the animation of the driver boarding their vehicle will be displayed.
|
||||
* Although the network is finicky, these times should compensate a beneficial visual delay.
|
||||
* The BFRs, the Switchblade, and the Flail are all untested.
|
||||
*/
|
||||
private val RaillessSeatAnimationTimes : Map[String, Int] = Map(
|
||||
"fury" -> 600,
|
||||
"quadassault" -> 600,
|
||||
"quadstealth" -> 600,
|
||||
"two_man_assault_buggy" -> 1000,
|
||||
"skyguard" -> 1300,
|
||||
"threemanheavybuggy" -> 1000,
|
||||
"twomanheavybuggy" -> 1800,
|
||||
"twomanhoverbuggy" -> 1800,
|
||||
"mediumtransport" -> 1300,
|
||||
"battlewagon" -> 1300,
|
||||
"thunderer" -> 1300,
|
||||
"aurora" -> 1300,
|
||||
"apc_tr" -> 2300,
|
||||
"apc_nc" -> 2300,
|
||||
"apc_vs" -> 2300,
|
||||
"prowler" -> 1000,
|
||||
"vanguard" -> 2000,
|
||||
"magrider" -> 1800,
|
||||
"ant" -> 2500,
|
||||
"ams" -> 1000,
|
||||
"router" -> 2500,
|
||||
"mosquito" -> 2000,
|
||||
"lightgunship" -> 2000,
|
||||
"wasp" -> 2000,
|
||||
"liberator" -> 1800,
|
||||
"vulture" -> 1800,
|
||||
"dropship" -> 2000,
|
||||
"galaxy_gunship" -> 2000,
|
||||
"lodestar" -> 2000,
|
||||
"phantasm" -> 1800
|
||||
).withDefaultValue(1000)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
|
|
@ -22,46 +22,32 @@ import scala.concurrent.duration._
|
|||
class VehicleSpawnControlServerVehicleOverride(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) {
|
||||
def LogId = "-overrider"
|
||||
|
||||
val vehicleGuide = context.actorOf(Props(classOf[VehicleSpawnControlGuided], pad), s"${context.parent.path.name}-guide")
|
||||
val driverControl = context.actorOf(Props(classOf[VehicleSpawnControlDriverControl], pad), s"${context.parent.path.name}-driver")
|
||||
|
||||
def receive : Receive = {
|
||||
case VehicleSpawnControl.Process.ServerVehicleOverride(entry) =>
|
||||
val vehicle = entry.vehicle
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
val vehicleFailState = vehicle.Health == 0 || vehicle.Position == Vector3.Zero
|
||||
val driverFailState = !entry.driver.isAlive || entry.driver.Continent != Continent.Id || (if(vehicle.HasGUID) { !entry.driver.VehicleSeated.contains(vehicle.GUID) } else { true })
|
||||
val driverFailState = !driver.isAlive || driver.Continent != pad.Continent || !vehicle.PassengerInSeat(driver).contains(0)
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad)
|
||||
if(vehicleFailState || driverFailState) {
|
||||
if(vehicleFailState) {
|
||||
trace(s"vehicle was already destroyed")
|
||||
if(pad.Railed) {
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad, Continent.Id)
|
||||
}
|
||||
}
|
||||
else {
|
||||
trace(s"driver is not ready")
|
||||
if(pad.Railed) {
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad, Continent.Id)
|
||||
}
|
||||
}
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.RevealPlayer(entry.driver.GUID, Continent.Id)
|
||||
vehicleGuide ! VehicleSpawnControl.Process.FinalClearance(entry)
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(order.DriverGUID)
|
||||
driverControl ! order
|
||||
}
|
||||
else {
|
||||
if(pad.Railed) {
|
||||
Continent.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad, Continent.Id)
|
||||
}
|
||||
if(entry.sendTo != ActorRef.noSender) {
|
||||
trace(s"telling ${entry.driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}")
|
||||
entry.sendTo ! VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad)
|
||||
context.system.scheduler.scheduleOnce(3000 milliseconds, vehicleGuide, VehicleSpawnControl.Process.StartGuided(entry))
|
||||
}
|
||||
trace(s"telling ${driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}")
|
||||
pad.Owner.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideStart(driver.Name, vehicle, pad)
|
||||
context.system.scheduler.scheduleOnce(4000 milliseconds, driverControl, order)
|
||||
}
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
context.parent ! msg
|
||||
|
||||
case msg @ VehicleSpawnControl.Process.FinalClearance(_) =>
|
||||
vehicleGuide ! msg
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,31 @@
|
|||
package net.psforever.objects.serverobject.painbox
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable}
|
||||
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions}
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.DefaultCancellable
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import services.ServiceManager
|
||||
import services.ServiceManager.Lookup
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
class PainboxControl(painbox: Painbox) extends Actor {
|
||||
var avatarService : ActorRef = Actor.noSender
|
||||
private[this] val log = org.log4s.getLogger(s"Painbox")
|
||||
//private[this] val log = org.log4s.getLogger(s"Painbox")
|
||||
private var painboxTick: Cancellable = DefaultCancellable.obj
|
||||
private var nearestDoor : Door = null
|
||||
|
||||
def receive : Receive = {
|
||||
case "startup" =>
|
||||
ServiceManager.serviceManager ! Lookup("avatar")
|
||||
nearestDoor = painbox.Owner.asInstanceOf[Building].Amenities.filter(x => x.isInstanceOf[Door])
|
||||
.map(x => x.asInstanceOf[Door])
|
||||
.sortBy(door => Vector3.DistanceSquared(painbox.Position, door.Position))
|
||||
.head
|
||||
|
||||
case ServiceManager.LookupResult("avatar", endpoint) =>
|
||||
avatarService = endpoint
|
||||
log.trace("PainboxControl: " + painbox.GUID + " Got avatar service " + endpoint)
|
||||
|
||||
context.become(Processing)
|
||||
painboxTick = context.system.scheduler.schedule(0 seconds,1 second, self, Painbox.Tick())
|
||||
painbox.Owner match {
|
||||
case obj : Building =>
|
||||
nearestDoor = obj.Amenities
|
||||
.collect { case door : Door => door }
|
||||
.minBy(door => Vector3.DistanceSquared(painbox.Position, door.Position))
|
||||
painboxTick = context.system.scheduler.schedule(0 seconds,1 second, self, Painbox.Tick())
|
||||
context.become(Processing)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -39,24 +33,21 @@ class PainboxControl(painbox: Painbox) extends Actor {
|
|||
def Processing : Receive = {
|
||||
case Painbox.Tick() =>
|
||||
//todo: Account for overlapping pain fields
|
||||
if(painbox.Owner.Faction == PlanetSideEmpire.NEUTRAL) return null
|
||||
if(painbox.Definition.HasNearestDoorDependency && nearestDoor.Open.isEmpty) return null
|
||||
|
||||
val playersToCheck = painbox.Owner.asInstanceOf[Building].PlayersInSOI
|
||||
if(playersToCheck.length == 0) return null
|
||||
// todo: Disable if no base power
|
||||
|
||||
val playersInRange = playersToCheck.filter(p =>
|
||||
p.Faction != painbox.Owner.Faction
|
||||
&& p.Health > 0
|
||||
&& Math.pow(p.Position.x - painbox.Position.x, 2) + Math.pow(p.Position.y - painbox.Position.y, 2) + Math.pow(p.Position.z - painbox.Position.z, 2) < Math.pow(painbox.Definition.Radius, 2)
|
||||
)
|
||||
|
||||
// Make 'em hurt.
|
||||
playersInRange.foreach({ p =>
|
||||
avatarService ! AvatarServiceMessage(p.Name, AvatarAction.EnvironmentalDamage(p.GUID, painbox.Definition.Damage))
|
||||
// todo: Pain module
|
||||
// todo: REK boosting
|
||||
})
|
||||
//todo: Pain module
|
||||
//todo: REK boosting
|
||||
val owner = painbox.Owner.asInstanceOf[Building]
|
||||
val faction = owner.Faction
|
||||
if(faction != PlanetSideEmpire.NEUTRAL && nearestDoor.Open.nonEmpty) {
|
||||
val events = owner.Zone.AvatarEvents
|
||||
val damage = painbox.Definition.Damage
|
||||
val radius = painbox.Definition.Radius * painbox.Definition.Radius
|
||||
val position = painbox.Position
|
||||
owner.PlayersInSOI
|
||||
.collect { case p if p.Faction != faction
|
||||
&& p.Health > 0
|
||||
&& Vector3.DistanceSquared(p.Position, position) < radius =>
|
||||
events ! AvatarServiceMessage(p.Name, AvatarAction.EnvironmentalDamage(p.GUID, damage))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,24 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
// Copyright (c) 2019 PSForever
|
||||
package net.psforever.objects.serverobject.resourcesilo
|
||||
|
||||
import akka.actor.{Actor, ActorRef}
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import services.ServiceManager.Lookup
|
||||
import services._
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Resource Silo`.
|
||||
* @param resourceSilo the `Resource Silo` object being governed
|
||||
*/
|
||||
class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = resourceSilo
|
||||
var avatarService : ActorRef = Actor.noSender
|
||||
private[this] val log = org.log4s.getLogger
|
||||
|
||||
def receive : Receive = {
|
||||
case "startup" =>
|
||||
ServiceManager.serviceManager ! Lookup("avatar")
|
||||
|
||||
case ServiceManager.LookupResult("avatar", endpoint) =>
|
||||
avatarService = endpoint
|
||||
log.trace("ResourceSiloControl: Silo " + resourceSilo.GUID + " Got avatar service " + endpoint)
|
||||
|
||||
// todo: This is just a temporary solution to drain NTU over time. When base object destruction is properly implemented NTU should be deducted when base objects repair themselves
|
||||
context.system.scheduler.schedule(5 second, 5 second, self, ResourceSilo.UpdateChargeLevel(-1))
|
||||
context.become(Processing)
|
||||
|
|
@ -43,7 +32,12 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
|
|||
case ResourceSilo.LowNtuWarning(enabled: Boolean) =>
|
||||
resourceSilo.LowNtuWarningOn = enabled
|
||||
log.trace(s"LowNtuWarning: Silo ${resourceSilo.GUID} low ntu warning set to $enabled")
|
||||
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.Owner.asInstanceOf[Building].GUID, 47, if(resourceSilo.LowNtuWarningOn) 1 else 0))
|
||||
val building = resourceSilo.Owner
|
||||
val zone = building.Zone
|
||||
building.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.Id,
|
||||
AvatarAction.PlanetsideAttribute(building.GUID, 47, if(resourceSilo.LowNtuWarningOn) 1 else 0)
|
||||
)
|
||||
|
||||
case ResourceSilo.UpdateChargeLevel(amount: Int) =>
|
||||
val siloChargeBeforeChange = resourceSilo.ChargeLevel
|
||||
|
|
@ -54,14 +48,18 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
|
|||
log.trace(s"UpdateChargeLevel: Silo ${resourceSilo.GUID} set to ${resourceSilo.ChargeLevel}")
|
||||
}
|
||||
|
||||
|
||||
val ntuBarLevel = scala.math.ceil((resourceSilo.ChargeLevel.toFloat / resourceSilo.MaximumCharge.toFloat) * 10).toInt
|
||||
// Only send updated capacitor display value to all clients if it has actually changed
|
||||
if(resourceSilo.CapacitorDisplay != ntuBarLevel) {
|
||||
log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from ${resourceSilo.CapacitorDisplay} to $ntuBarLevel")
|
||||
resourceSilo.CapacitorDisplay = ntuBarLevel
|
||||
resourceSilo.Owner.Actor ! Building.SendMapUpdate(all_clients = true)
|
||||
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay))
|
||||
val building = resourceSilo.Owner
|
||||
val zone = building.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.Id,
|
||||
AvatarAction.PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay)
|
||||
)
|
||||
}
|
||||
|
||||
val ntuIsLow = resourceSilo.ChargeLevel.toFloat / resourceSilo.MaximumCharge.toFloat < 0.2f
|
||||
|
|
@ -71,20 +69,25 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
|
|||
self ! ResourceSilo.LowNtuWarning(enabled = true)
|
||||
}
|
||||
|
||||
|
||||
val building = resourceSilo.Owner
|
||||
val zone = building.Zone
|
||||
if(resourceSilo.ChargeLevel == 0 && siloChargeBeforeChange > 0) {
|
||||
// Oops, someone let the base run out of power. Shut it all down.
|
||||
//todo: Make base neutral if silo hits zero NTU
|
||||
|
||||
//todo: temporarily disabled until warpgates can bring ANTs from sanctuary, otherwise we'd be stuck in a situation with an unpowered base and no way to get an ANT to refill it.
|
||||
// avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(PlanetSideGUID(resourceSilo.Owner.asInstanceOf[Building].ModelId), 48, 1))
|
||||
// zone.AvatarEvents ! AvatarServiceMessage(
|
||||
// zone.Id,
|
||||
// AvatarAction.PlanetsideAttribute(PlanetSideGUID(building.MapId), 48, 1)
|
||||
// )
|
||||
} else if (siloChargeBeforeChange == 0 && resourceSilo.ChargeLevel > 0) {
|
||||
// Power restored. Reactor Online. Sensors Online. Weapons Online. All systems nominal.
|
||||
//todo: Check generator is online before starting up
|
||||
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.Owner.asInstanceOf[Building].GUID, 48, 0))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.Id,
|
||||
AvatarAction.PlanetsideAttribute(building.GUID, 48, 0)
|
||||
)
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,27 @@ package net.psforever.objects.serverobject.structures
|
|||
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.zones.{Zone => World }
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
/**
|
||||
* Amenities are elements of the game that belong to other elements of the game.
|
||||
* Their owners are also elements of the game, ones that understand that they belong to a specific `Zone` object.
|
||||
* @see `PlanetSideServerObject`
|
||||
* @see `Zone`
|
||||
* @see `ZoneAware`
|
||||
*/
|
||||
trait AmenityOwner extends PlanetSideServerObject {
|
||||
private var zoneRef : World = World.Nowhere
|
||||
|
||||
def Zone_=(zone : World) : World = {
|
||||
zoneRef = zone
|
||||
Zone
|
||||
}
|
||||
|
||||
def Zone : World = zoneRef
|
||||
}
|
||||
|
||||
/**
|
||||
* Amenities are elements of the game that belong to other elements of the game.<br>
|
||||
* <br>
|
||||
|
|
@ -17,7 +36,7 @@ import net.psforever.types.{PlanetSideEmpire, Vector3}
|
|||
*/
|
||||
abstract class Amenity extends PlanetSideServerObject {
|
||||
/** what other entity has authority over this amenity; usually either a building or a vehicle */
|
||||
private var owner : PlanetSideServerObject = Building.NoBuilding
|
||||
private var owner : AmenityOwner = Building.NoBuilding
|
||||
/** if the entity exists at a specific position relative to the owner's position */
|
||||
private var offset : Option[Vector3] = None
|
||||
|
||||
|
|
@ -27,17 +46,16 @@ abstract class Amenity extends PlanetSideServerObject {
|
|||
* Reference the object that is in direct association with (is superior to) this one.
|
||||
* @return the object associated as this object's "owner"
|
||||
*/
|
||||
def Owner : PlanetSideServerObject = owner
|
||||
def Owner : AmenityOwner = owner
|
||||
|
||||
/**
|
||||
* Set an object to have a direct association with (be superior to) this one.
|
||||
* @see `Amenity.AmenityTarget`
|
||||
* @param obj the object trying to become associated as this object's "owner"
|
||||
* @tparam T a validation of the type of object that can be an owner
|
||||
* @return the object associated as this object's "owner"
|
||||
*/
|
||||
def Owner_=[T : Amenity.AmenityTarget](obj : T) : PlanetSideServerObject = {
|
||||
owner = obj.asInstanceOf[PlanetSideServerObject]
|
||||
def Owner_=(obj : AmenityOwner) : AmenityOwner = {
|
||||
owner = obj
|
||||
Owner
|
||||
}
|
||||
|
||||
|
|
@ -61,24 +79,3 @@ abstract class Amenity extends PlanetSideServerObject {
|
|||
case _ => super.Continent
|
||||
}
|
||||
}
|
||||
|
||||
object Amenity {
|
||||
/**
|
||||
* A `trait` for validating the type of object that can be allowed to become an `Amenity` object's `Owner`.<br>
|
||||
* <br>
|
||||
* The `Owner` defaults to a type of `PlanetSideServerObject` in reference type;
|
||||
* but, that distinction is mainly to allow for a common ancestor with appropriate methods.
|
||||
* Only certain types of `PlanetSideServerObject` are formally allowed to be owners.
|
||||
* In execution, the `T` is the type of object that implicitly converts into an acceptable type of sub-object.
|
||||
* The companion object maintains the hardcoded conversions.
|
||||
* If such an implicit conversion does not exist, the assignment is unacceptable at compile time.
|
||||
* @tparam T the permitted type of object
|
||||
*/
|
||||
sealed trait AmenityTarget[T]
|
||||
|
||||
object AmenityTarget {
|
||||
import net.psforever.objects.Vehicle
|
||||
implicit object BuildingTarget extends AmenityTarget[Building] { }
|
||||
implicit object VehicleTarget extends AmenityTarget[Vehicle] { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ import net.psforever.objects.zones.Zone
|
|||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
class Building(private val building_guid : Int, private val map_id : Int, private val zone : Zone, private val buildingType : StructureType.Value, private val buildingDefinition : ObjectDefinition) extends PlanetSideServerObject {
|
||||
class Building(private val building_guid : Int, private val map_id : Int, val zone : Zone, private val buildingType : StructureType.Value, private val buildingDefinition : ObjectDefinition) extends PlanetSideServerObject
|
||||
with AmenityOwner {
|
||||
/**
|
||||
* The map_id is the identifier number used in BuildingInfoUpdateMessage. This is the index that the building appears in the MPO file starting from index 1
|
||||
* The GUID is the identifier number used in SetEmpireMessage / Facility hacking / PlanetSideAttributeMessage.
|
||||
|
|
@ -23,6 +24,7 @@ class Building(private val building_guid : Int, private val map_id : Int, privat
|
|||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
private var amenities : List[Amenity] = List.empty
|
||||
private var playersInSOI : List[Player] = List.empty
|
||||
super.Zone_=(zone)
|
||||
|
||||
GUID = PlanetSideGUID(building_guid)
|
||||
|
||||
|
|
@ -44,7 +46,7 @@ class Building(private val building_guid : Int, private val map_id : Int, privat
|
|||
}
|
||||
|
||||
def CaptureConsoleIsHacked : Boolean = {
|
||||
Amenities.filter(x => x.Definition == GlobalDefinitions.capture_terminal).headOption.asInstanceOf[Option[CaptureTerminal]] match {
|
||||
Amenities.find(x => x.Definition == GlobalDefinitions.capture_terminal).asInstanceOf[Option[CaptureTerminal]] match {
|
||||
case Some(obj: CaptureTerminal) =>
|
||||
obj.HackedBy.isDefined
|
||||
case None => false
|
||||
|
|
@ -58,8 +60,6 @@ class Building(private val building_guid : Int, private val map_id : Int, privat
|
|||
playersInSOI
|
||||
}
|
||||
|
||||
def Zone : Zone = zone
|
||||
|
||||
def Info : (
|
||||
Int,
|
||||
Boolean, PlanetSideEmpire.Value, Long, PlanetSideEmpire.Value,
|
||||
|
|
@ -128,9 +128,11 @@ class Building(private val building_guid : Int, private val map_id : Int, privat
|
|||
|
||||
def BuildingType : StructureType.Value = buildingType
|
||||
|
||||
override def Continent : String = zone.Id
|
||||
override def Zone_=(zone : Zone) : Zone = Zone //building never leaves zone after being set in constructor
|
||||
|
||||
override def Continent_=(zone : String) : String = Continent
|
||||
override def Continent : String = Zone.Id
|
||||
|
||||
override def Continent_=(zone : String) : String = Continent //building never leaves zone after being set in constructor
|
||||
|
||||
def Definition: ObjectDefinition = buildingDefinition
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,22 +11,17 @@ import services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, Gala
|
|||
class BuildingControl(building : Building) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = building
|
||||
var galaxyService : ActorRef = Actor.noSender
|
||||
var localService : ActorRef = Actor.noSender
|
||||
private[this] val log = org.log4s.getLogger
|
||||
|
||||
override def preStart = {
|
||||
log.trace(s"Starting BuildingControl for ${building.GUID} / ${building.MapId}")
|
||||
ServiceManager.serviceManager ! Lookup("galaxy")
|
||||
ServiceManager.serviceManager ! Lookup("local")
|
||||
}
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case ServiceManager.LookupResult("galaxy", endpoint) =>
|
||||
galaxyService = endpoint
|
||||
log.trace("BuildingControl: Building " + building.GUID + " Got galaxy service " + endpoint)
|
||||
case ServiceManager.LookupResult("local", endpoint) =>
|
||||
localService = endpoint
|
||||
log.trace("BuildingControl: Building " + building.GUID + " Got local service " + endpoint)
|
||||
case FactionAffinity.ConvertFactionAffinity(faction) =>
|
||||
val originalAffinity = building.Faction
|
||||
if(originalAffinity != (building.Faction = faction)) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import net.psforever.objects._
|
|||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||
import services.{Service, ServiceManager}
|
||||
import services.Service
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -18,7 +18,6 @@ import scala.concurrent.duration._
|
|||
* @param term the proximity unit (terminal)
|
||||
*/
|
||||
class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||
var service : ActorRef = ActorRef.noSender
|
||||
var terminalAction : Cancellable = DefaultCancellable.obj
|
||||
val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]()
|
||||
val log = org.log4s.getLogger
|
||||
|
|
@ -33,10 +32,6 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
def Start : Receive = checkBehavior
|
||||
.orElse {
|
||||
case Service.Startup() =>
|
||||
ServiceManager.serviceManager ! ServiceManager.Lookup("local")
|
||||
|
||||
case ServiceManager.LookupResult("local", ref) =>
|
||||
service = ref
|
||||
context.become(Run)
|
||||
|
||||
case _ => ;
|
||||
|
|
@ -45,15 +40,14 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
def Run : Receive = checkBehavior
|
||||
.orElse(hackableBehavior)
|
||||
.orElse {
|
||||
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
|
||||
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
||||
Use(target, term.Continent, sender)
|
||||
}
|
||||
|
||||
case CommonMessages.Use(_, Some((target : PlanetSideGameObject, callback : ActorRef))) =>
|
||||
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
||||
Use(target, term.Continent, callback)
|
||||
}
|
||||
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
|
||||
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
||||
Use(target, term.Continent, sender)
|
||||
}
|
||||
case CommonMessages.Use(_, Some((target : PlanetSideGameObject, callback : ActorRef))) =>
|
||||
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
||||
Use(target, term.Continent, callback)
|
||||
}
|
||||
|
||||
case CommonMessages.Use(_, _) =>
|
||||
log.warn(s"unexpected format for CommonMessages.Use in this context")
|
||||
|
|
@ -68,7 +62,7 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
val proxDef = term.Definition.asInstanceOf[ProximityDefinition]
|
||||
val validateFunc : PlanetSideGameObject=>Boolean = term.Validate(proxDef.UseRadius * proxDef.UseRadius, proxDef.Validations)
|
||||
val callbackList = callbacks.toList
|
||||
term.Targets.zipWithIndex.foreach({ case((target, index)) =>
|
||||
term.Targets.zipWithIndex.foreach({ case(target, index) =>
|
||||
if(validateFunc(target)) {
|
||||
callbackList.lift(index) match {
|
||||
case Some(cback) =>
|
||||
|
|
@ -92,7 +86,7 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
def Use(target : PlanetSideGameObject, zone : String, callback : ActorRef) : Unit = {
|
||||
val hadNoUsers = term.NumberUsers == 0
|
||||
if(term.AddUser(target)) {
|
||||
log.info(s"ProximityTerminal.Use: unit ${term.Definition.Name}@${term.GUID.guid} will act on $target")
|
||||
log.trace(s"ProximityTerminal.Use: unit ${term.Definition.Name}@${term.GUID.guid} will act on $target")
|
||||
//add callback
|
||||
callbacks += callback
|
||||
//activation
|
||||
|
|
@ -101,7 +95,7 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
terminalAction.cancel
|
||||
terminalAction = context.system.scheduler.schedule(500 milliseconds, medDef.Interval, self, ProximityTerminalControl.TerminalAction())
|
||||
service ! Terminal.StartProximityEffect(term)
|
||||
TerminalObject.Owner.Zone.LocalEvents ! Terminal.StartProximityEffect(term)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -114,13 +108,13 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
val previousUsers = term.NumberUsers
|
||||
val hadUsers = previousUsers > 0
|
||||
if(whereTarget > -1 && term.RemoveUser(target)) {
|
||||
log.info(s"ProximityTerminal.Unuse: unit ${term.Definition.Name}@${term.GUID.guid} will cease operation on $target")
|
||||
log.trace(s"ProximityTerminal.Unuse: unit ${term.Definition.Name}@${term.GUID.guid} will cease operation on $target")
|
||||
//remove callback
|
||||
callbacks.remove(whereTarget)
|
||||
//de-activation (global / local)
|
||||
if(term.NumberUsers == 0 && hadUsers) {
|
||||
terminalAction.cancel
|
||||
service ! Terminal.StopProximityEffect(term)
|
||||
TerminalObject.Owner.Zone.LocalEvents ! Terminal.StopProximityEffect(term)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ import net.psforever.objects.serverobject.turret.FacilityTurret
|
|||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import services.Service
|
||||
import services.avatar.AvatarService
|
||||
import services.local.LocalService
|
||||
import services.vehicle.VehicleService
|
||||
|
||||
import scala.collection.concurrent.TrieMap
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
|
@ -89,6 +92,10 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
/** calculate a duration from a given interaction's participants */
|
||||
private var hotspotTimeFunc : (SourceEntry, SourceEntry)=>FiniteDuration = Zone.HotSpot.Rules.NoTime
|
||||
/** */
|
||||
private var avatarEvents : ActorRef = ActorRef.noSender
|
||||
/** */
|
||||
private var localEvents : ActorRef = ActorRef.noSender
|
||||
/** */
|
||||
private var vehicleEvents : ActorRef = ActorRef.noSender
|
||||
|
||||
/**
|
||||
|
|
@ -110,9 +117,8 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
*/
|
||||
def Init(implicit context : ActorContext) : Unit = {
|
||||
if(accessor == ActorRef.noSender) {
|
||||
implicit val guid : NumberPoolHub = this.guid //passed into builderObject.Build implicitly
|
||||
SetupNumberPools()
|
||||
accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystem.AllocateNumberPoolActors(guid))), s"$Id-uns")
|
||||
accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], this.guid, UniqueNumberSystem.AllocateNumberPoolActors(this.guid))), s"$Id-uns")
|
||||
ground = context.actorOf(Props(classOf[ZoneGroundActor], this, equipmentOnGround), s"$Id-ground")
|
||||
deployables = context.actorOf(Props(classOf[ZoneDeployableActor], this, constructions), s"$Id-deployables")
|
||||
transport = context.actorOf(Props(classOf[ZoneVehicleActor], this, vehicles), s"$Id-vehicles")
|
||||
|
|
@ -120,6 +126,11 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
projector = context.actorOf(Props(classOf[ZoneHotSpotProjector], this), s"$Id-hotpots")
|
||||
soi = context.actorOf(Props(classOf[SphereOfInfluenceActor], this), s"$Id-soi")
|
||||
|
||||
avatarEvents = context.actorOf(Props(classOf[AvatarService], this), s"$Id-avatar-events")
|
||||
localEvents = context.actorOf(Props(classOf[LocalService], this), s"$Id-local-events")
|
||||
vehicleEvents = context.actorOf(Props(classOf[VehicleService], this), s"$Id-vehicle-events")
|
||||
|
||||
implicit val guid : NumberPoolHub = this.guid //passed into builderObject.Build implicitly
|
||||
BuildLocalObjects(context, guid)
|
||||
BuildSupportObjects()
|
||||
MakeBuildings(context)
|
||||
|
|
@ -492,12 +503,24 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
*/
|
||||
def ClientInitialization() : Zone = this
|
||||
|
||||
def AvatarEvents : ActorRef = avatarEvents
|
||||
|
||||
def AvatarEvents_=(bus : ActorRef) : ActorRef = {
|
||||
avatarEvents = bus
|
||||
AvatarEvents
|
||||
}
|
||||
|
||||
def LocalEvents : ActorRef = localEvents
|
||||
|
||||
def LocalEvents_=(bus : ActorRef) : ActorRef = {
|
||||
localEvents = bus
|
||||
LocalEvents
|
||||
}
|
||||
|
||||
def VehicleEvents : ActorRef = vehicleEvents
|
||||
|
||||
def VehicleEvents_=(bus : ActorRef) : ActorRef = {
|
||||
if(vehicleEvents == ActorRef.noSender) {
|
||||
vehicleEvents = bus
|
||||
}
|
||||
vehicleEvents = bus
|
||||
VehicleEvents
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ class ZoneHotSpotProjector(zone : Zone) extends Actor {
|
|||
}
|
||||
newSpot
|
||||
}
|
||||
log.info(s"new coordinate remapping function provided; updating ${redoneSpots.size} hotspots")
|
||||
log.trace(s"new coordinate remapping function provided; updating ${redoneSpots.size} hotspots")
|
||||
zone.HotSpots = redoneSpots
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class ZoneVehicleActor(zone : Zone, vehicleList : ListBuffer[Vehicle]) extends A
|
|||
}
|
||||
else {
|
||||
vehicleList += vehicle
|
||||
vehicle.Continent = zone.Id
|
||||
vehicle.Zone = zone
|
||||
vehicle.Actor = context.actorOf(Props(classOf[VehicleControl], vehicle), s"${vehicle.Definition.Name}_${vehicle.GUID.guid}")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,20 @@
|
|||
package services.avatar
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
|
||||
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMessageParent, PlacementData}
|
||||
import services.avatar.support.{CorpseRemovalActor, DroppedItemRemover}
|
||||
import services.{GenericEventBus, RemoverActor, Service}
|
||||
|
||||
class AvatarService extends Actor {
|
||||
private val undertaker : ActorRef = context.actorOf(Props[CorpseRemovalActor], "corpse-removal-agent")
|
||||
private val janitor = context.actorOf(Props[DroppedItemRemover], "item-remover-agent")
|
||||
class AvatarService(zone : Zone) extends Actor {
|
||||
private val undertaker : ActorRef = context.actorOf(Props[CorpseRemovalActor], s"${zone.Id}-corpse-removal-agent")
|
||||
private val janitor = context.actorOf(Props[DroppedItemRemover], s"${zone.Id}-item-remover-agent")
|
||||
|
||||
private [this] val log = org.log4s.getLogger
|
||||
|
||||
override def preStart = {
|
||||
log.info("Starting...")
|
||||
log.trace(s"Awaiting ${zone.Id} avatar events ...")
|
||||
}
|
||||
|
||||
val AvatarEvents = new GenericEventBus[AvatarServiceResponse] //AvatarEventBus
|
||||
|
|
@ -88,7 +89,7 @@ class AvatarService extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", Service.defaultPlayerGUID, AvatarResponse.DestroyDisplay(killer, victim, method, unk))
|
||||
)
|
||||
case AvatarAction.DropItem(player_guid, item, zone) =>
|
||||
case AvatarAction.DropItem(player_guid, item, _) =>
|
||||
val definition = item.Definition
|
||||
val objectData = DroppedItemData(
|
||||
PlacementData(item.Position, item.Orientation),
|
||||
|
|
@ -173,7 +174,7 @@ class AvatarService extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ProjectileState(projectile_guid, shot_pos, shot_vel, shot_orient, sequence, end, target))
|
||||
)
|
||||
case AvatarAction.PickupItem(player_guid, zone, target, slot, item, unk) =>
|
||||
case AvatarAction.PickupItem(player_guid, _, target, slot, item, unk) =>
|
||||
janitor forward RemoverActor.ClearSpecific(List(item), zone)
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, {
|
||||
|
|
@ -193,7 +194,7 @@ class AvatarService extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.PutDownFDU(player_guid))
|
||||
)
|
||||
case AvatarAction.Release(player, zone, time) =>
|
||||
case AvatarAction.Release(player, _, time) =>
|
||||
undertaker forward RemoverActor.AddTask(player, zone, time)
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player.GUID, AvatarResponse.Release(player))
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.galaxy
|
||||
|
||||
import net.psforever.packet.game.BuildingInfoUpdateMessage
|
||||
|
||||
object GalaxyAction {
|
||||
trait Action
|
||||
|
||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Action
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.galaxy
|
||||
|
||||
import net.psforever.objects.zones.HotSpotInfo
|
||||
import net.psforever.packet.game.BuildingInfoUpdateMessage
|
||||
|
||||
object GalaxyResponse {
|
||||
trait Response
|
||||
|
||||
final case class HotSpotUpdate(zone_id : Int, priority : Int, host_spot_info : List[HotSpotInfo]) extends Response
|
||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response
|
||||
}
|
||||
|
|
@ -19,33 +19,44 @@ class GalaxyService extends Actor {
|
|||
case Service.Join(faction) if "TRNCVS".containsSlice(faction) =>
|
||||
val path = s"/$faction/Galaxy"
|
||||
val who = sender()
|
||||
log.info(s"$who has joined $path")
|
||||
log.trace(s"$who has joined $path")
|
||||
GalaxyEvents.subscribe(who, path)
|
||||
|
||||
case Service.Join(_) =>
|
||||
case Service.Join("galaxy") =>
|
||||
val path = s"/Galaxy"
|
||||
val who = sender()
|
||||
log.info(s"$who has joined $path")
|
||||
log.trace(s"$who has joined $path")
|
||||
GalaxyEvents.subscribe(who, path)
|
||||
|
||||
case Service.Join(channel) =>
|
||||
val path = s"/$channel/Galaxy"
|
||||
val who = sender()
|
||||
log.trace(s"$who has joined $path")
|
||||
GalaxyEvents.subscribe(who, path)
|
||||
|
||||
case Service.Leave(None) =>
|
||||
GalaxyEvents.unsubscribe(sender())
|
||||
|
||||
case Service.Leave(_) =>
|
||||
val path = s"/Galaxy"
|
||||
case Service.Leave(Some(channel)) =>
|
||||
val path = s"/$channel/Galaxy"
|
||||
val who = sender()
|
||||
log.info(s"$who has left $path")
|
||||
GalaxyEvents.unsubscribe(who, path)
|
||||
log.trace(s"$who has left $path")
|
||||
GalaxyEvents.unsubscribe(sender(), path)
|
||||
|
||||
case Service.LeaveAll() =>
|
||||
GalaxyEvents.unsubscribe(sender())
|
||||
|
||||
case GalaxyServiceMessage(action) =>
|
||||
case GalaxyServiceMessage(forChannel, action) =>
|
||||
action match {
|
||||
case GalaxyAction.MapUpdate(msg: BuildingInfoUpdateMessage) =>
|
||||
GalaxyEvents.publish(
|
||||
GalaxyServiceResponse(s"/Galaxy", GalaxyResponse.MapUpdate(msg))
|
||||
)
|
||||
|
||||
case GalaxyAction.TransferPassenger(player_guid, temp_channel, vehicle, vehicle_to_delete) =>
|
||||
GalaxyEvents.publish(
|
||||
GalaxyServiceResponse(s"/$forChannel/Galaxy", GalaxyResponse.TransferPassenger(temp_channel, vehicle, vehicle_to_delete))
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,19 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.galaxy
|
||||
|
||||
final case class GalaxyServiceMessage(actionMessage : GalaxyAction.Action)
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetSideGUID}
|
||||
|
||||
final case class GalaxyServiceMessage(forChannel : String, actionMessage : GalaxyAction.Action)
|
||||
|
||||
object GalaxyServiceMessage {
|
||||
def apply(actionMessage : GalaxyAction.Action) : GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage)
|
||||
}
|
||||
|
||||
object GalaxyAction {
|
||||
trait Action
|
||||
|
||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Action
|
||||
|
||||
final case class TransferPassenger(player_guid : PlanetSideGUID, temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Action
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.galaxy
|
||||
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.zones.HotSpotInfo
|
||||
import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetSideGUID}
|
||||
import services.GenericEventBusMsg
|
||||
|
||||
final case class GalaxyServiceResponse(toChannel : String,
|
||||
replyMessage : GalaxyResponse.Response
|
||||
) extends GenericEventBusMsg
|
||||
|
||||
object GalaxyResponse {
|
||||
trait Response
|
||||
|
||||
final case class HotSpotUpdate(zone_id : Int, priority : Int, host_spot_info : List[HotSpotInfo]) extends Response
|
||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response
|
||||
|
||||
final case class TransferPassenger(temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.local
|
||||
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.terminals.CaptureTerminal
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
object LocalAction {
|
||||
trait Action
|
||||
|
||||
final case class AlertDestroyDeployable(player_guid : PlanetSideGUID, obj : PlanetSideGameObject with Deployable) extends Action
|
||||
final case class DeployableMapIcon(player_guid : PlanetSideGUID, behavior : DeploymentAction.Value, deployInfo : DeployableInfo) extends Action
|
||||
final case class DoorOpens(player_guid : PlanetSideGUID, continent : Zone, door : Door) extends Action
|
||||
final case class DoorCloses(player_guid : PlanetSideGUID, door_guid : PlanetSideGUID) extends Action
|
||||
final case class HackClear(player_guid : PlanetSideGUID, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
||||
final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, duration: Int, unk2 : Long = 8L) extends Action
|
||||
final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) extends Action
|
||||
final case class HackCaptureTerminal(player_guid : PlanetSideGUID, continent : Zone, target : CaptureTerminal, unk1 : Long, unk2 : Long = 8L, isResecured : Boolean) extends Action
|
||||
final case class RouterTelepadTransport(player_guid : PlanetSideGUID, passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Action
|
||||
final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Action
|
||||
final case class ToggleTeleportSystem(player_guid : PlanetSideGUID, router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Action
|
||||
final case class TriggerEffect(player_guid : PlanetSideGUID, effect : String, target : PlanetSideGUID) extends Action
|
||||
final case class TriggerEffectInfo(player_guid : PlanetSideGUID, effect : String, target : PlanetSideGUID, unk1 : Boolean, unk2 : Long) extends Action
|
||||
final case class TriggerEffectLocation(player_guid : PlanetSideGUID, effect : String, pos : Vector3, orient : Vector3) extends Action
|
||||
final case class TriggerSound(player_guid : PlanetSideGUID, sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Action
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.local
|
||||
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
object LocalResponse {
|
||||
trait Response
|
||||
|
||||
final case class AlertDestroyDeployable(obj : PlanetSideGameObject with Deployable) extends Response
|
||||
final case class DeployableMapIcon(action : DeploymentAction.Value, deployInfo : DeployableInfo) extends Response
|
||||
final case class DoorOpens(door_guid : PlanetSideGUID) extends Response
|
||||
final case class DoorCloses(door_guid : PlanetSideGUID) extends Response
|
||||
final case class EliminateDeployable(obj : PlanetSideGameObject with Deployable, object_guid : PlanetSideGUID, pos : Vector3) extends Response
|
||||
final case class HackClear(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||
final case class HackObject(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||
final case class HackCaptureTerminal(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long, isResecured: Boolean) extends Response
|
||||
final case class ObjectDelete(item_guid : PlanetSideGUID, unk : Int) extends Response
|
||||
final case class ProximityTerminalEffect(object_guid : PlanetSideGUID, effectState : Boolean) extends Response
|
||||
final case class RouterTelepadMessage(msg : String) extends Response
|
||||
final case class RouterTelepadTransport(passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Response
|
||||
final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Response
|
||||
final case class ToggleTeleportSystem(router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Response
|
||||
final case class TriggerEffect(target: PlanetSideGUID, effect: String, effectInfo: Option[TriggeredEffect] = None, triggeredLocation: Option[TriggeredEffectLocation] = None) extends Response
|
||||
final case class TriggerSound(sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Response
|
||||
}
|
||||
|
|
@ -5,47 +5,38 @@ import akka.actor.{Actor, ActorRef, Props}
|
|||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, ProximityUnit, Terminal}
|
||||
import net.psforever.objects.zones.{InterstellarCluster, Zone}
|
||||
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, Terminal}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects._
|
||||
import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation}
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.types.Vector3
|
||||
import services.local.support._
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import services.{GenericEventBus, RemoverActor, Service, ServiceManager}
|
||||
import services.{GenericEventBus, RemoverActor, Service}
|
||||
|
||||
import scala.util.Success
|
||||
import scala.concurrent.duration._
|
||||
import akka.pattern.ask
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.vehicles.{Utility, UtilityType}
|
||||
import services.ServiceManager.Lookup
|
||||
import services.support.SupportActor
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class LocalService extends Actor {
|
||||
private val doorCloser = context.actorOf(Props[DoorCloseActor], "local-door-closer")
|
||||
private val hackClearer = context.actorOf(Props[HackClearActor], "local-hack-clearer")
|
||||
private val hackCapturer = context.actorOf(Props[HackCaptureActor], "local-hack-capturer")
|
||||
private val engineer = context.actorOf(Props[DeployableRemover], "deployable-remover-agent")
|
||||
private val teleportDeployment : ActorRef = context.actorOf(Props[RouterTelepadActivation], "telepad-activate-agent")
|
||||
class LocalService(zone : Zone) extends Actor {
|
||||
private val doorCloser = context.actorOf(Props[DoorCloseActor], s"${zone.Id}-local-door-closer")
|
||||
private val hackClearer = context.actorOf(Props[HackClearActor], s"${zone.Id}-local-hack-clearer")
|
||||
private val hackCapturer = context.actorOf(Props[HackCaptureActor], s"${zone.Id}-local-hack-capturer")
|
||||
private val engineer = context.actorOf(Props[DeployableRemover], s"${zone.Id}-deployable-remover-agent")
|
||||
private val teleportDeployment : ActorRef = context.actorOf(Props[RouterTelepadActivation], s"${zone.Id}-telepad-activate-agent")
|
||||
private [this] val log = org.log4s.getLogger
|
||||
var cluster : ActorRef = Actor.noSender
|
||||
|
||||
override def preStart = {
|
||||
log.info("Starting...")
|
||||
ServiceManager.serviceManager ! Lookup("cluster")
|
||||
log.trace(s"Awaiting ${zone.Id} local events ...")
|
||||
}
|
||||
|
||||
val LocalEvents = new GenericEventBus[LocalServiceResponse]
|
||||
|
||||
def receive = {
|
||||
case ServiceManager.LookupResult("cluster", endpoint) =>
|
||||
cluster = endpoint
|
||||
log.trace("LocalService got cluster service " + endpoint)
|
||||
|
||||
def receive : Receive = {
|
||||
case Service.Join(channel) =>
|
||||
val path = s"/$channel/Local"
|
||||
val who = sender()
|
||||
|
|
@ -74,7 +65,7 @@ class LocalService extends Actor {
|
|||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DeployableMapIcon(behavior, deployInfo))
|
||||
)
|
||||
case LocalAction.DoorOpens(player_guid, zone, door) =>
|
||||
case LocalAction.DoorOpens(player_guid, _, door) =>
|
||||
doorCloser ! DoorCloseActor.DoorIsOpen(door, zone)
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DoorOpens(door.GUID))
|
||||
|
|
@ -87,21 +78,19 @@ class LocalService extends Actor {
|
|||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackClear(target.GUID, unk1, unk2))
|
||||
)
|
||||
case LocalAction.HackTemporarily(player_guid, zone, target, unk1, duration, unk2) =>
|
||||
case LocalAction.HackTemporarily(player_guid, _, target, unk1, duration, unk2) =>
|
||||
hackClearer ! HackClearActor.ObjectIsHacked(target, zone, unk1, unk2, duration)
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackObject(target.GUID, unk1, unk2))
|
||||
)
|
||||
case LocalAction.ClearTemporaryHack(_, target) =>
|
||||
hackClearer ! HackClearActor.ObjectIsResecured(target)
|
||||
case LocalAction.HackCaptureTerminal(player_guid, zone, target, unk1, unk2, isResecured) =>
|
||||
|
||||
case LocalAction.HackCaptureTerminal(player_guid, _, target, unk1, unk2, isResecured) =>
|
||||
// When a CC is hacked (or resecured) all amenities for the base should be unhacked
|
||||
val hackableAmenities = target.Owner.asInstanceOf[Building].Amenities.filter(x => x.isInstanceOf[Hackable]).map(x => x.asInstanceOf[Amenity with Hackable])
|
||||
hackableAmenities.foreach(amenity =>
|
||||
if(amenity.HackedBy.isDefined) { hackClearer ! HackClearActor.ObjectIsResecured(amenity) }
|
||||
)
|
||||
|
||||
if(isResecured){
|
||||
hackCapturer ! HackCaptureActor.ClearHack(target, zone)
|
||||
} else {
|
||||
|
|
@ -114,7 +103,6 @@ class LocalService extends Actor {
|
|||
hackCapturer ! HackCaptureActor.ObjectIsHacked(target, zone, unk1, unk2, duration = 1 nanosecond)
|
||||
}
|
||||
}
|
||||
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackCaptureTerminal(target.GUID, unk1, unk2, isResecured))
|
||||
)
|
||||
|
|
@ -150,70 +138,60 @@ class LocalService extends Actor {
|
|||
}
|
||||
|
||||
//response from DoorCloseActor
|
||||
case DoorCloseActor.CloseTheDoor(door_guid, zone_id) =>
|
||||
case DoorCloseActor.CloseTheDoor(door_guid, _) =>
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$zone_id/Local", Service.defaultPlayerGUID, LocalResponse.DoorCloses(door_guid))
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", Service.defaultPlayerGUID, LocalResponse.DoorCloses(door_guid))
|
||||
)
|
||||
|
||||
//response from HackClearActor
|
||||
case HackClearActor.ClearTheHack(target_guid, zone_id, unk1, unk2) =>
|
||||
case HackClearActor.ClearTheHack(target_guid, _, unk1, unk2) =>
|
||||
log.warn(s"Clearing hack for $target_guid")
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$zone_id/Local", Service.defaultPlayerGUID, LocalResponse.HackClear(target_guid, unk1, unk2))
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", Service.defaultPlayerGUID, LocalResponse.HackClear(target_guid, unk1, unk2))
|
||||
)
|
||||
|
||||
//message from ProximityTerminalControl
|
||||
case Terminal.StartProximityEffect(terminal) =>
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/${terminal.Owner.Continent}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, true))
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, true))
|
||||
)
|
||||
case Terminal.StopProximityEffect(terminal) =>
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/${terminal.Owner.Continent}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, false))
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, false))
|
||||
)
|
||||
|
||||
case HackCaptureActor.HackTimeoutReached(capture_terminal_guid, zone_id, _, _, hackedByFaction) =>
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
ask(cluster, InterstellarCluster.GetWorld(zone_id))(1 seconds).onComplete {
|
||||
case Success(InterstellarCluster.GiveWorld(_, zone)) =>
|
||||
val terminal = zone.asInstanceOf[Zone].GUID(capture_terminal_guid).get.asInstanceOf[CaptureTerminal]
|
||||
val building = terminal.Owner.asInstanceOf[Building]
|
||||
|
||||
// todo: Move this to a function for Building
|
||||
var ntuLevel = 0
|
||||
building.Amenities.find(_.Definition == GlobalDefinitions.resource_silo).asInstanceOf[Option[ResourceSilo]] match {
|
||||
case Some(obj: ResourceSilo) =>
|
||||
ntuLevel = obj.CapacitorDisplay.toInt
|
||||
case _ =>
|
||||
// Base has no NTU silo - likely a tower / cavern CC
|
||||
ntuLevel = 1
|
||||
}
|
||||
|
||||
if(ntuLevel > 0) {
|
||||
log.info(s"Setting base ${building.GUID} / MapId: ${building.MapId} as owned by $hackedByFaction")
|
||||
|
||||
building.Faction = hackedByFaction
|
||||
self ! LocalServiceMessage(zone.Id, LocalAction.SetEmpire(building.GUID, hackedByFaction))
|
||||
} else {
|
||||
log.info("Base hack completed, but base was out of NTU.")
|
||||
}
|
||||
|
||||
// Reset CC back to normal operation
|
||||
self ! LocalServiceMessage(zone.Id, LocalAction.HackCaptureTerminal(PlanetSideGUID(-1), zone, terminal, 0, 8L, isResecured = true))
|
||||
//todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. The attribute above is a workaround
|
||||
self ! HackClearActor.ClearTheHack(building.GUID, zone.Id, 3212836864L, 8L)
|
||||
case Success(_) =>
|
||||
log.warn("Got success from InterstellarCluster.GetWorld but didn't know how to handle it")
|
||||
|
||||
case scala.util.Failure(_) => log.warn(s"LocalService Failed to get zone when hack timeout was reached")
|
||||
case HackCaptureActor.HackTimeoutReached(capture_terminal_guid, _, _, _, hackedByFaction) =>
|
||||
val terminal = zone.GUID(capture_terminal_guid).get.asInstanceOf[CaptureTerminal]
|
||||
val building = terminal.Owner.asInstanceOf[Building]
|
||||
// todo: Move this to a function for Building
|
||||
var ntuLevel = building.Amenities.find(_.Definition == GlobalDefinitions.resource_silo) match {
|
||||
case Some(obj: ResourceSilo) =>
|
||||
obj.CapacitorDisplay.toInt
|
||||
case _ =>
|
||||
// Base has no NTU silo - likely a tower / cavern CC
|
||||
1
|
||||
}
|
||||
|
||||
if(ntuLevel > 0) {
|
||||
log.info(s"Setting base ${building.GUID} / MapId: ${building.MapId} as owned by $hackedByFaction")
|
||||
|
||||
building.Faction = hackedByFaction
|
||||
self ! LocalServiceMessage(zone.Id, LocalAction.SetEmpire(building.GUID, hackedByFaction))
|
||||
} else {
|
||||
log.info("Base hack completed, but base was out of NTU.")
|
||||
}
|
||||
|
||||
// Reset CC back to normal operation
|
||||
self ! LocalServiceMessage(zone.Id, LocalAction.HackCaptureTerminal(PlanetSideGUID(-1), zone, terminal, 0, 8L, isResecured = true))
|
||||
//todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. The attribute above is a workaround
|
||||
self ! HackClearActor.ClearTheHack(building.GUID, zone.Id, 3212836864L, 8L)
|
||||
|
||||
//message to Engineer
|
||||
case LocalServiceMessage.Deployables(msg) =>
|
||||
engineer forward msg
|
||||
|
||||
//message(s) from Engineer
|
||||
case msg @ DeployableRemover.EliminateDeployable(obj : TurretDeployable, guid, pos, zone) =>
|
||||
case msg @ DeployableRemover.EliminateDeployable(obj : TurretDeployable, guid, pos, _) =>
|
||||
val seats = obj.Seats.values
|
||||
if(seats.count(_.isOccupied) > 0) {
|
||||
val wasKickedByDriver = false //TODO yeah, I don't know
|
||||
|
|
@ -230,27 +208,27 @@ class LocalService extends Actor {
|
|||
context.system.scheduler.scheduleOnce(Duration.create(2, "seconds"), self, msg)
|
||||
}
|
||||
else {
|
||||
EliminateDeployable(obj, guid, pos, zone.Id)
|
||||
EliminateDeployable(obj, guid, pos)
|
||||
}
|
||||
|
||||
case DeployableRemover.EliminateDeployable(obj : BoomerDeployable, guid, pos, zone) =>
|
||||
EliminateDeployable(obj, guid, pos, zone.Id)
|
||||
case DeployableRemover.EliminateDeployable(obj : BoomerDeployable, guid, pos, _) =>
|
||||
EliminateDeployable(obj, guid, pos)
|
||||
obj.Trigger match {
|
||||
case Some(trigger) =>
|
||||
log.warn(s"LocalService: deconstructing boomer in ${zone.Id}, but trigger@${trigger.GUID.guid} still exists")
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case DeployableRemover.EliminateDeployable(obj : TelepadDeployable, guid, pos, zone) =>
|
||||
case DeployableRemover.EliminateDeployable(obj : TelepadDeployable, guid, pos, _) =>
|
||||
obj.Active = false
|
||||
//ClearSpecific will also remove objects that do not have GUID's; we may not have a GUID at this time
|
||||
teleportDeployment ! SupportActor.ClearSpecific(List(obj), zone)
|
||||
EliminateDeployable(obj, guid, pos, zone.Id)
|
||||
EliminateDeployable(obj, guid, pos)
|
||||
|
||||
case DeployableRemover.EliminateDeployable(obj, guid, pos, zone) =>
|
||||
EliminateDeployable(obj, guid, pos, zone.Id)
|
||||
case DeployableRemover.EliminateDeployable(obj, guid, pos, _) =>
|
||||
EliminateDeployable(obj, guid, pos)
|
||||
|
||||
case DeployableRemover.DeleteTrigger(trigger_guid, zone) =>
|
||||
case DeployableRemover.DeleteTrigger(trigger_guid, _) =>
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", Service.defaultPlayerGUID, LocalResponse.ObjectDelete(trigger_guid, 0))
|
||||
)
|
||||
|
|
@ -260,7 +238,7 @@ class LocalService extends Actor {
|
|||
teleportDeployment forward msg
|
||||
|
||||
//from RouterTelepadActivation
|
||||
case RouterTelepadActivation.ActivateTeleportSystem(telepad, zone) =>
|
||||
case RouterTelepadActivation.ActivateTeleportSystem(telepad, _) =>
|
||||
val remoteTelepad = telepad.asInstanceOf[TelepadDeployable]
|
||||
remoteTelepad.Active = true
|
||||
zone.GUID(remoteTelepad.Router) match {
|
||||
|
|
@ -294,13 +272,13 @@ class LocalService extends Actor {
|
|||
}
|
||||
case _ =>
|
||||
log.error(s"ActivateTeleportSystem: vehicle@${router.GUID.guid} in ${zone.Id} is not a router?")
|
||||
RouterTelepadError(remoteTelepad, zone, "@Telepad_NoDeploy_RouterLost")
|
||||
RouterTelepadError(remoteTelepad, "@Telepad_NoDeploy_RouterLost")
|
||||
}
|
||||
case Some(o) =>
|
||||
log.error(s"ActivateTeleportSystem: ${o.Definition.Name}@${o.GUID.guid} in ${zone.Id} is not a router")
|
||||
RouterTelepadError(remoteTelepad, zone, "@Telepad_NoDeploy_RouterLost")
|
||||
RouterTelepadError(remoteTelepad, "@Telepad_NoDeploy_RouterLost")
|
||||
case None =>
|
||||
RouterTelepadError(remoteTelepad, zone, "@Telepad_NoDeploy_RouterLost")
|
||||
RouterTelepadError(remoteTelepad, "@Telepad_NoDeploy_RouterLost")
|
||||
}
|
||||
|
||||
//synchronized damage calculations
|
||||
|
|
@ -315,10 +293,9 @@ class LocalService extends Actor {
|
|||
/**
|
||||
* na
|
||||
* @param telepad na
|
||||
* @param zone na
|
||||
* @param msg na
|
||||
*/
|
||||
def RouterTelepadError(telepad : TelepadDeployable, zone : Zone, msg : String) : Unit = {
|
||||
def RouterTelepadError(telepad : TelepadDeployable, msg : String) : Unit = {
|
||||
telepad.OwnerName match {
|
||||
case Some(name) =>
|
||||
LocalEvents.publish(
|
||||
|
|
@ -344,11 +321,10 @@ class LocalService extends Actor {
|
|||
* @param guid the deployable objects globally unique identifier;
|
||||
* may be a former identifier
|
||||
* @param position the deployable's position
|
||||
* @param zoneId the zone where the deployable is currently placed
|
||||
*/
|
||||
def EliminateDeployable(obj : PlanetSideGameObject with Deployable, guid : PlanetSideGUID, position : Vector3, zoneId : String) : Unit = {
|
||||
def EliminateDeployable(obj : PlanetSideGameObject with Deployable, guid : PlanetSideGUID, position : Vector3) : Unit = {
|
||||
LocalEvents.publish(
|
||||
LocalServiceResponse(s"/$zoneId/Local", Service.defaultPlayerGUID, LocalResponse.EliminateDeployable(obj, guid, position))
|
||||
LocalServiceResponse(s"/${zone.Id}/Local", Service.defaultPlayerGUID, LocalResponse.EliminateDeployable(obj, guid, position))
|
||||
)
|
||||
obj.OwnerName match {
|
||||
case Some(name) =>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.local
|
||||
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.terminals.CaptureTerminal
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{DeployableInfo, DeploymentAction, PlanetSideGUID, TriggeredSound}
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
final case class LocalServiceMessage(forChannel : String, actionMessage : LocalAction.Action)
|
||||
|
||||
object LocalServiceMessage {
|
||||
|
|
@ -8,3 +19,23 @@ object LocalServiceMessage {
|
|||
|
||||
final case class Telepads(msg : Any)
|
||||
}
|
||||
|
||||
object LocalAction {
|
||||
trait Action
|
||||
|
||||
final case class AlertDestroyDeployable(player_guid : PlanetSideGUID, obj : PlanetSideGameObject with Deployable) extends Action
|
||||
final case class DeployableMapIcon(player_guid : PlanetSideGUID, behavior : DeploymentAction.Value, deployInfo : DeployableInfo) extends Action
|
||||
final case class DoorOpens(player_guid : PlanetSideGUID, continent : Zone, door : Door) extends Action
|
||||
final case class DoorCloses(player_guid : PlanetSideGUID, door_guid : PlanetSideGUID) extends Action
|
||||
final case class HackClear(player_guid : PlanetSideGUID, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
||||
final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, duration: Int, unk2 : Long = 8L) extends Action
|
||||
final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) extends Action
|
||||
final case class HackCaptureTerminal(player_guid : PlanetSideGUID, continent : Zone, target : CaptureTerminal, unk1 : Long, unk2 : Long = 8L, isResecured : Boolean) extends Action
|
||||
final case class RouterTelepadTransport(player_guid : PlanetSideGUID, passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Action
|
||||
final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Action
|
||||
final case class ToggleTeleportSystem(player_guid : PlanetSideGUID, router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Action
|
||||
final case class TriggerEffect(player_guid : PlanetSideGUID, effect : String, target : PlanetSideGUID) extends Action
|
||||
final case class TriggerEffectInfo(player_guid : PlanetSideGUID, effect : String, target : PlanetSideGUID, unk1 : Boolean, unk2 : Long) extends Action
|
||||
final case class TriggerEffectLocation(player_guid : PlanetSideGUID, effect : String, pos : Vector3, orient : Vector3) extends Action
|
||||
final case class TriggerSound(player_guid : PlanetSideGUID, sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Action
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,37 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.local
|
||||
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import services.GenericEventBusMsg
|
||||
|
||||
final case class LocalServiceResponse(toChannel : String,
|
||||
avatar_guid : PlanetSideGUID,
|
||||
replyMessage : LocalResponse.Response
|
||||
) extends GenericEventBusMsg
|
||||
|
||||
object LocalResponse {
|
||||
trait Response
|
||||
|
||||
final case class AlertDestroyDeployable(obj : PlanetSideGameObject with Deployable) extends Response
|
||||
final case class DeployableMapIcon(action : DeploymentAction.Value, deployInfo : DeployableInfo) extends Response
|
||||
final case class DoorOpens(door_guid : PlanetSideGUID) extends Response
|
||||
final case class DoorCloses(door_guid : PlanetSideGUID) extends Response
|
||||
final case class EliminateDeployable(obj : PlanetSideGameObject with Deployable, object_guid : PlanetSideGUID, pos : Vector3) extends Response
|
||||
final case class HackClear(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||
final case class HackObject(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||
final case class HackCaptureTerminal(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long, isResecured: Boolean) extends Response
|
||||
final case class ObjectDelete(item_guid : PlanetSideGUID, unk : Int) extends Response
|
||||
final case class ProximityTerminalAction(terminal : Terminal with ProximityUnit, target : PlanetSideGameObject) extends Response
|
||||
final case class ProximityTerminalEffect(object_guid : PlanetSideGUID, effectState : Boolean) extends Response
|
||||
final case class RouterTelepadMessage(msg : String) extends Response
|
||||
final case class RouterTelepadTransport(passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Response
|
||||
final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Response
|
||||
final case class ToggleTeleportSystem(router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Response
|
||||
final case class TriggerEffect(target: PlanetSideGUID, effect: String, effectInfo: Option[TriggeredEffect] = None, triggeredLocation: Option[TriggeredEffectLocation] = None) extends Response
|
||||
final case class TriggerSound(sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.vehicle
|
||||
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.types.{BailType, DriveState, Vector3}
|
||||
|
||||
object VehicleAction {
|
||||
trait 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, bailType : BailType.Value, unk2 : Boolean) extends Action
|
||||
final case class EquipmentInSlot(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, equipment : Equipment) extends Action
|
||||
final case class InventoryState(player_guid : PlanetSideGUID, obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Action
|
||||
final case class InventoryState2(player_guid : PlanetSideGUID, obj_guid : PlanetSideGUID, parent_guid : PlanetSideGUID, value : Int) extends Action
|
||||
final case class KickPassenger(player_guid : PlanetSideGUID, unk1 : Int, unk2 : Boolean, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class LoadVehicle(player_guid : PlanetSideGUID, vehicle : Vehicle, vtype : Int, vguid : PlanetSideGUID, vdata : ConstructorData) extends Action
|
||||
final case class MountVehicle(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, seat : Int) extends Action
|
||||
final case class ObjectDelete(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class Ownership(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class PlanetsideAttribute(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Action
|
||||
final case class SeatPermissions(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, seat_group : Int, permission : Long) extends Action
|
||||
final case class StowEquipment(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
|
||||
final case class UnloadVehicle(player_guid : PlanetSideGUID, continent : Zone, vehicle : Vehicle, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class UnstowEquipment(player_guid : PlanetSideGUID, item_guid : PlanetSideGUID) extends Action
|
||||
final case class VehicleState(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, unk1 : Int, pos : Vector3, ang : Vector3, vel : Option[Vector3], unk2 : Option[Int], unk3 : Int, unk4 : Int, wheel_direction : Int, unk5 : Boolean, unk6 : Boolean) extends Action
|
||||
final case class SendResponse(player_guid: PlanetSideGUID, msg : PlanetSideGamePacket) extends Action
|
||||
final case class UpdateAmsSpawnPoint(zone : Zone) extends Action
|
||||
|
||||
final case class TransferPassengerChannel(player_guid : PlanetSideGUID, temp_channel : String, new_channel : String, vehicle : Vehicle) extends Action
|
||||
final case class TransferPassenger(player_guid : PlanetSideGUID, temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Action
|
||||
|
||||
final case class ForceDismountVehicleCargo(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Action
|
||||
final case class KickCargo(player_guid : PlanetSideGUID, cargo : Vehicle, speed : Int, delay : Long) extends Action
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.vehicle
|
||||
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.types.{BailType, DriveState, Vector3}
|
||||
|
||||
object VehicleResponse {
|
||||
trait Response
|
||||
|
||||
final case class AttachToRails(vehicle_guid : PlanetSideGUID, rails_guid : PlanetSideGUID) extends Response
|
||||
final case class ChildObjectState(object_guid : PlanetSideGUID, pitch : Float, yaw : Float) extends Response
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Response
|
||||
final case class DeployRequest(object_guid : PlanetSideGUID, state : DriveState.Value, unk1 : Int, unk2 : Boolean, pos : Vector3) extends Response
|
||||
final case class DetachFromRails(vehicle_guid : PlanetSideGUID, rails_guid : PlanetSideGUID, rails_pos : Vector3, rails_rot : Float) extends Response
|
||||
final case class DismountVehicle(bailType : BailType.Value , unk2 : Boolean) extends Response
|
||||
final case class EquipmentInSlot(pkt : ObjectCreateMessage) extends Response
|
||||
final case class HitHint(source_guid : PlanetSideGUID) extends Response
|
||||
final case class InventoryState(obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Response
|
||||
final case class InventoryState2(obj_guid : PlanetSideGUID, parent_guid : PlanetSideGUID, value : Int) extends Response
|
||||
final case class KickPassenger(seat_num : Int, kickedByDriver : Boolean, vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class LoadVehicle(vehicle : Vehicle, vtype : Int, vguid : PlanetSideGUID, vdata : ConstructorData) extends Response
|
||||
final case class MountVehicle(object_guid : PlanetSideGUID, seat : Int) extends Response
|
||||
final case class Ownership(vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class PlanetsideAttribute(vehicle_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Response
|
||||
final case class ResetSpawnPad(pad_guid : PlanetSideGUID) extends Response
|
||||
final case class RevealPlayer(player_guid : PlanetSideGUID) extends Response
|
||||
final case class SeatPermissions(vehicle_guid : PlanetSideGUID, seat_group : Int, permission : Long) extends Response
|
||||
final case class StowEquipment(vehicle_guid : PlanetSideGUID, slot : Int, itype : Int, iguid : PlanetSideGUID, idata : ConstructorData) extends Response
|
||||
final case class UnloadVehicle(vehicle : Vehicle, vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class UnstowEquipment(item_guid : PlanetSideGUID) extends Response
|
||||
final case class VehicleState(vehicle_guid : PlanetSideGUID, unk1 : Int, pos : Vector3, ang : Vector3, vel : Option[Vector3], unk2 : Option[Int], unk3 : Int, unk4 : Int, wheel_direction : Int, unk5 : Boolean, unk6 : Boolean) extends Response
|
||||
final case class SendResponse(msg: PlanetSideGamePacket) extends Response
|
||||
final case class UpdateAmsSpawnPoint(list : List[SpawnTube]) extends Response
|
||||
|
||||
final case class TransferPassengerChannel(old_channel : String, temp_channel : String, vehicle : Vehicle) extends Response
|
||||
final case class TransferPassenger(temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Response
|
||||
|
||||
final case class ForceDismountVehicleCargo(vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Response
|
||||
final case class KickCargo(cargo : Vehicle, speed : Int, delay : Long) extends Response
|
||||
}
|
||||
|
|
@ -16,13 +16,13 @@ import services.{GenericEventBus, RemoverActor, Service}
|
|||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class VehicleService extends Actor {
|
||||
private val vehicleDecon : ActorRef = context.actorOf(Props[VehicleRemover], "vehicle-decon-agent")
|
||||
private val turretUpgrade : ActorRef = context.actorOf(Props[TurretUpgrader], "turret-upgrade-agent")
|
||||
class VehicleService(zone : Zone) extends Actor {
|
||||
private val vehicleDecon : ActorRef = context.actorOf(Props[VehicleRemover], s"${zone.Id}-vehicle-decon-agent")
|
||||
private val turretUpgrade : ActorRef = context.actorOf(Props[TurretUpgrader], s"${zone.Id}-turret-upgrade-agent")
|
||||
private [this] val log = org.log4s.getLogger
|
||||
|
||||
override def preStart = {
|
||||
log.info("Starting...")
|
||||
log.trace(s"Awaiting ${zone.Id} vehicle events ...")
|
||||
}
|
||||
|
||||
val VehicleEvents = new GenericEventBus[VehicleServiceResponse]
|
||||
|
|
@ -135,10 +135,6 @@ class VehicleService extends Actor {
|
|||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.TransferPassengerChannel(old_channel, temp_channel, vehicle))
|
||||
)
|
||||
case VehicleAction.TransferPassenger(player_guid, temp_channel, vehicle, vehicle_to_delete) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.TransferPassenger(temp_channel, vehicle, vehicle_to_delete))
|
||||
)
|
||||
|
||||
case VehicleAction.ForceDismountVehicleCargo(player_guid, vehicle_guid, bailed, requestedByPassenger, kicked) =>
|
||||
VehicleEvents.publish(
|
||||
|
|
@ -159,37 +155,57 @@ class VehicleService extends Actor {
|
|||
case VehicleServiceMessage.TurretUpgrade(msg) =>
|
||||
turretUpgrade forward msg
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.ConcealPlayer(player_guid, zone_id) =>
|
||||
//from VehicleSpawnControl, etc.
|
||||
case VehicleSpawnPad.ConcealPlayer(player_guid) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ConcealPlayer(player_guid))
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ConcealPlayer(player_guid))
|
||||
)
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.AttachToRails(vehicle, pad, zone_id) =>
|
||||
case VehicleSpawnPad.AttachToRails(vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.AttachToRails(vehicle.GUID, pad.GUID))
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.AttachToRails(vehicle.GUID, pad.GUID))
|
||||
)
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.DetachFromRails(vehicle, pad, zone_id) =>
|
||||
case VehicleSpawnPad.StartPlayerSeatedInVehicle(driver_name, vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.DetachFromRails(vehicle.GUID, pad.GUID, pad.Position, pad.Orientation.z))
|
||||
VehicleServiceResponse(s"/$driver_name/Vehicle", Service.defaultPlayerGUID, VehicleResponse.StartPlayerSeatedInVehicle(vehicle, pad))
|
||||
)
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.ResetSpawnPad(pad, zone_id) =>
|
||||
case VehicleSpawnPad.PlayerSeatedInVehicle(driver_name, vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ResetSpawnPad(pad.GUID))
|
||||
VehicleServiceResponse(s"/$driver_name/Vehicle", Service.defaultPlayerGUID, VehicleResponse.PlayerSeatedInVehicle(vehicle, pad))
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.RevealPlayer(player_guid, zone_id) =>
|
||||
case VehicleSpawnPad.ServerVehicleOverrideStart(driver_name, vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.RevealPlayer(player_guid))
|
||||
VehicleServiceResponse(s"/$driver_name/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ServerVehicleOverrideStart(vehicle, pad))
|
||||
)
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.LoadVehicle(vehicle, zone) =>
|
||||
case VehicleSpawnPad.ServerVehicleOverrideEnd(driver_name, vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$driver_name/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ServerVehicleOverrideEnd(vehicle, pad))
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.DetachFromRails(vehicle, pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.DetachFromRails(vehicle.GUID, pad.GUID, pad.Position, pad.Orientation.z))
|
||||
)
|
||||
case VehicleSpawnPad.ResetSpawnPad(pad) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ResetSpawnPad(pad.GUID))
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.RevealPlayer(player_guid) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.RevealPlayer(player_guid))
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.PeriodicReminder(to, reason, data) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$to/Vehicle", Service.defaultPlayerGUID, VehicleResponse.PeriodicReminder(reason, data))
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.LoadVehicle(vehicle) =>
|
||||
val definition = vehicle.Definition
|
||||
val vtype = definition.ObjectId
|
||||
val vguid = vehicle.GUID
|
||||
|
|
@ -201,12 +217,12 @@ class VehicleService extends Actor {
|
|||
//avoid unattended vehicle spawning blocking the pad; user should mount (and does so normally) to reset decon timer
|
||||
vehicleDecon forward RemoverActor.AddTask(vehicle, zone, Some(30 seconds))
|
||||
|
||||
//from VehicleSpawnControl
|
||||
case VehicleSpawnPad.DisposeVehicle(vehicle, zone) =>
|
||||
case VehicleSpawnPad.DisposeVehicle(vehicle) =>
|
||||
vehicleDecon forward RemoverActor.AddTask(vehicle, zone, Some(0 seconds))
|
||||
vehicleDecon forward RemoverActor.HurrySpecific(List(vehicle), zone)
|
||||
|
||||
//correspondence from WorldSessionActor
|
||||
case VehicleServiceMessage.AMSDeploymentChange(zone) =>
|
||||
case VehicleServiceMessage.AMSDeploymentChange(_) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.UpdateAmsSpawnPoint(AmsSpawnPoints(zone)))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.vehicle
|
||||
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.{PlanetSideGameObject, Vehicle}
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.types.{BailType, DriveState, Vector3}
|
||||
|
||||
final case class VehicleServiceMessage(forChannel : String, actionMessage : VehicleAction.Action)
|
||||
|
||||
|
|
@ -16,3 +21,32 @@ object VehicleServiceMessage {
|
|||
|
||||
final case class AMSDeploymentChange(zone : Zone)
|
||||
}
|
||||
|
||||
object VehicleAction {
|
||||
trait 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, bailType : BailType.Value, unk2 : Boolean) extends Action
|
||||
final case class EquipmentInSlot(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, equipment : Equipment) extends Action
|
||||
final case class InventoryState(player_guid : PlanetSideGUID, obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Action
|
||||
final case class InventoryState2(player_guid : PlanetSideGUID, obj_guid : PlanetSideGUID, parent_guid : PlanetSideGUID, value : Int) extends Action
|
||||
final case class KickPassenger(player_guid : PlanetSideGUID, unk1 : Int, unk2 : Boolean, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class LoadVehicle(player_guid : PlanetSideGUID, vehicle : Vehicle, vtype : Int, vguid : PlanetSideGUID, vdata : ConstructorData) extends Action
|
||||
final case class MountVehicle(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, seat : Int) extends Action
|
||||
final case class ObjectDelete(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class Ownership(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class PlanetsideAttribute(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Action
|
||||
final case class SeatPermissions(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, seat_group : Int, permission : Long) extends Action
|
||||
final case class StowEquipment(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
|
||||
final case class UnloadVehicle(player_guid : PlanetSideGUID, continent : Zone, vehicle : Vehicle, vehicle_guid : PlanetSideGUID) extends Action
|
||||
final case class UnstowEquipment(player_guid : PlanetSideGUID, item_guid : PlanetSideGUID) extends Action
|
||||
final case class VehicleState(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, unk1 : Int, pos : Vector3, ang : Vector3, vel : Option[Vector3], unk2 : Option[Int], unk3 : Int, unk4 : Int, wheel_direction : Int, unk5 : Boolean, unk6 : Boolean) extends Action
|
||||
final case class SendResponse(player_guid: PlanetSideGUID, msg : PlanetSideGamePacket) extends Action
|
||||
final case class UpdateAmsSpawnPoint(zone : Zone) extends Action
|
||||
|
||||
final case class TransferPassengerChannel(player_guid : PlanetSideGUID, temp_channel : String, new_channel : String, vehicle : Vehicle) extends Action
|
||||
|
||||
final case class ForceDismountVehicleCargo(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Action
|
||||
final case class KickCargo(player_guid : PlanetSideGUID, cargo : Vehicle, speed : Int, delay : Long) extends Action
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,57 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package services.vehicle
|
||||
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad.Reminders
|
||||
import net.psforever.objects.{PlanetSideGameObject, Vehicle}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{BailType, DriveState, Vector3}
|
||||
import services.GenericEventBusMsg
|
||||
|
||||
final case class VehicleServiceResponse(toChannel : String,
|
||||
avatar_guid : PlanetSideGUID,
|
||||
replyMessage : VehicleResponse.Response
|
||||
) extends GenericEventBusMsg
|
||||
|
||||
object VehicleResponse {
|
||||
trait Response
|
||||
|
||||
final case class ChildObjectState(object_guid : PlanetSideGUID, pitch : Float, yaw : Float) extends Response
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Response
|
||||
final case class DeployRequest(object_guid : PlanetSideGUID, state : DriveState.Value, unk1 : Int, unk2 : Boolean, pos : Vector3) extends Response
|
||||
final case class DismountVehicle(bailType : BailType.Value , unk2 : Boolean) extends Response
|
||||
final case class EquipmentInSlot(pkt : ObjectCreateMessage) extends Response
|
||||
final case class HitHint(source_guid : PlanetSideGUID) extends Response
|
||||
final case class InventoryState(obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Response
|
||||
final case class InventoryState2(obj_guid : PlanetSideGUID, parent_guid : PlanetSideGUID, value : Int) extends Response
|
||||
final case class KickPassenger(seat_num : Int, kickedByDriver : Boolean, vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class LoadVehicle(vehicle : Vehicle, vtype : Int, vguid : PlanetSideGUID, vdata : ConstructorData) extends Response
|
||||
final case class MountVehicle(object_guid : PlanetSideGUID, seat : Int) extends Response
|
||||
final case class Ownership(vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class PlanetsideAttribute(vehicle_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Long) extends Response
|
||||
final case class RevealPlayer(player_guid : PlanetSideGUID) extends Response
|
||||
final case class SeatPermissions(vehicle_guid : PlanetSideGUID, seat_group : Int, permission : Long) extends Response
|
||||
final case class StowEquipment(vehicle_guid : PlanetSideGUID, slot : Int, itype : Int, iguid : PlanetSideGUID, idata : ConstructorData) extends Response
|
||||
final case class UnloadVehicle(vehicle : Vehicle, vehicle_guid : PlanetSideGUID) extends Response
|
||||
final case class UnstowEquipment(item_guid : PlanetSideGUID) extends Response
|
||||
final case class VehicleState(vehicle_guid : PlanetSideGUID, unk1 : Int, pos : Vector3, ang : Vector3, vel : Option[Vector3], unk2 : Option[Int], unk3 : Int, unk4 : Int, wheel_direction : Int, unk5 : Boolean, unk6 : Boolean) extends Response
|
||||
final case class SendResponse(msg: PlanetSideGamePacket) extends Response
|
||||
final case class UpdateAmsSpawnPoint(list : List[SpawnTube]) extends Response
|
||||
|
||||
final case class AttachToRails(vehicle_guid : PlanetSideGUID, rails_guid : PlanetSideGUID) extends Response
|
||||
final case class StartPlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad) extends Response
|
||||
final case class PlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad) extends Response
|
||||
final case class DetachFromRails(vehicle_guid : PlanetSideGUID, rails_guid : PlanetSideGUID, rails_pos : Vector3, rails_rot : Float) extends Response
|
||||
final case class ServerVehicleOverrideStart(vehicle : Vehicle, pad : VehicleSpawnPad) extends Response
|
||||
final case class ServerVehicleOverrideEnd(vehicle : Vehicle, pad : VehicleSpawnPad) extends Response
|
||||
final case class ResetSpawnPad(pad_guid : PlanetSideGUID) extends Response
|
||||
final case class PeriodicReminder(reason : Reminders.Value, data : Option[Any] = None) extends Response
|
||||
|
||||
final case class TransferPassengerChannel(old_channel : String, temp_channel : String, vehicle : Vehicle) extends Response
|
||||
|
||||
final case class ForceDismountVehicleCargo(vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Response
|
||||
final case class KickCargo(cargo : Vehicle, speed : Int, delay : Long) extends Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,499 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.pad.process.{AutoDriveControls, VehicleSpawnControlGuided}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class AutoDriveControlsTest extends Specification {
|
||||
"CancelEntry" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
def exampleTest(vehicle : Vehicle) : Boolean = { vehicle.Position == Vector3(1,1,1) }
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.CancelEarly(exampleTest)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Cancel
|
||||
setting.Data mustEqual None
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.CancelEarly(exampleTest)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Position mustEqual Vector3.Zero
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(1,1,1)
|
||||
setting.Validate(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.CancelEarly(exampleTest)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.CompletionTest(vehicle) mustEqual true //always true
|
||||
}
|
||||
}
|
||||
|
||||
"Climb" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mosquito)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Climb(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Climb
|
||||
setting.Data mustEqual Some(10.5f)
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val vehicle_fury = Vehicle(GlobalDefinitions.fury)
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Climb(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
setting.Validate(vehicle) mustEqual true //mosquito is a flying vehicle
|
||||
setting.Validate(vehicle_fury) mustEqual false
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Climb(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Position mustEqual Vector3.Zero
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(0,0,10.5f)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
}
|
||||
|
||||
"Distance" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Distance(Vector3.Zero, 10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Wait
|
||||
setting.Data mustEqual None
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Distance(Vector3.Zero, 10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3.Zero
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3(1,0,0)
|
||||
setting.Validate(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Distance(Vector3.Zero, 10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Position = Vector3(0,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(10.5f,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(11,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
vehicle.Position = Vector3(0,11,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
vehicle.Position = Vector3(0,0,11)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(7.5f,7.5f,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
}
|
||||
|
||||
"DistanceFromHere" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.DistanceFromHere(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Wait
|
||||
setting.Data mustEqual None
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.DistanceFromHere(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3.Zero
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3(1,0,0)
|
||||
setting.Validate(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.DistanceFromHere(10.5f)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Position = Vector3(0,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(10.5f,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(11,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
vehicle.Position = Vector3(0,11,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
vehicle.Position = Vector3(0,0,11)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Position = Vector3(7.5f,7.5f,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
}
|
||||
|
||||
"Drive" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Drive(3)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Drive
|
||||
setting.Data mustEqual Some(3)
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Drive(3)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Validate(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Drive(3)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
|
||||
vehicle.Velocity = Vector3.Zero
|
||||
vehicle.Velocity mustEqual Some(Vector3.Zero)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
|
||||
vehicle.Velocity = Vector3(1,0,0)
|
||||
vehicle.Velocity mustEqual Some(Vector3(1,0,0))
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
"FirstGear" should {
|
||||
val veh_def = GlobalDefinitions.mediumtransport
|
||||
val vehicle = Vehicle(veh_def)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.FirstGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Drive
|
||||
setting.Data mustEqual Some(0)
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.FirstGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Validate(vehicle) mustEqual true //always true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.FirstGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3.Zero
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3(1,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"data" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.FirstGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
setting.Data mustEqual Some(0)
|
||||
setting.Validate(vehicle)
|
||||
setting.Data mustEqual Some(veh_def.AutoPilotSpeed1)
|
||||
}
|
||||
}
|
||||
|
||||
"ForTime" should {
|
||||
val veh_def = GlobalDefinitions.mediumtransport
|
||||
val vehicle = Vehicle(veh_def)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.ForTime(1200L)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Wait
|
||||
setting.Data mustEqual None
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.ForTime(1200L)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Validate(vehicle) mustEqual true //always true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.ForTime(1200L)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
|
||||
Thread.sleep(1100)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
|
||||
Thread.sleep(200)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
}
|
||||
|
||||
"SecondGear" should {
|
||||
val veh_def = GlobalDefinitions.mediumtransport
|
||||
val vehicle = Vehicle(veh_def)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.SecondGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Drive
|
||||
setting.Data mustEqual Some(0)
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.SecondGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Validate(vehicle) mustEqual true //always true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.SecondGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3.Zero
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3(1,0,0)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"data" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.SecondGear()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
setting.Data mustEqual Some(0)
|
||||
setting.Validate(vehicle)
|
||||
setting.Data mustEqual Some(veh_def.AutoPilotSpeed2)
|
||||
}
|
||||
}
|
||||
|
||||
"Stop" should {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Stop()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Stop
|
||||
setting.Data mustEqual None
|
||||
setting.Delay mustEqual 200L
|
||||
}
|
||||
|
||||
"validate" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Stop()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Validate(vehicle) mustEqual true //always true
|
||||
}
|
||||
|
||||
"completion" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.Stop()
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.CompletionTest(vehicle) mustEqual true //always true
|
||||
}
|
||||
}
|
||||
|
||||
"TurnBy" should {
|
||||
"create" in {
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.TurnBy(35.5f, 23)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
setting.Type mustEqual AutoDriveControls.State.Turn
|
||||
setting.Data mustEqual Some(23)
|
||||
setting.Delay mustEqual 100L
|
||||
}
|
||||
|
||||
"validate (velocity)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.TurnBy(35.5f, 23)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity mustEqual None
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
vehicle.Velocity = Vector3(1,1,1)
|
||||
setting.Validate(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"validate (wheel direction = 15)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.TurnBy(35.5f, 15)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Velocity = Vector3(1,1,1)
|
||||
setting.Validate(vehicle) mustEqual false
|
||||
}
|
||||
|
||||
"completion (passing 35.5-up)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.TurnBy(35.5f, 25)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Orientation mustEqual Vector3.Zero
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Orientation = Vector3(0,0,34.5f)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Orientation = Vector3(0,0,35f)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Orientation = Vector3(0,0,36.0f)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
|
||||
"completion (passing 35.5 down)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
val config : AutoDriveControls.Configuration = AutoDriveControls.TurnBy(-35.5f, 25)
|
||||
val setting : AutoDriveControls.Setting = config.Create
|
||||
|
||||
vehicle.Orientation = Vector3(0,0,40f)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Orientation = Vector3(0,0,5f)
|
||||
setting.CompletionTest(vehicle) mustEqual false
|
||||
vehicle.Orientation = Vector3(0,0,4f)
|
||||
setting.CompletionTest(vehicle) mustEqual true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GuidedControlTest1 extends ActorTest {
|
||||
"VehicleSpawnControlGuided" should {
|
||||
"unguided" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
val driver = Player(Avatar("", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
driver.VehicleSeated = vehicle.GUID
|
||||
val sendTo = TestProbe()
|
||||
val order = VehicleSpawnControl.Order(driver, vehicle, sendTo.ref)
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
pad.GUID = PlanetSideGUID(1)
|
||||
pad.Railed = false //suppress certain events
|
||||
val guided = system.actorOf(Props(classOf[VehicleSpawnControlGuided], pad), "pad")
|
||||
|
||||
guided ! VehicleSpawnControl.Process.StartGuided(order)
|
||||
val msg = sendTo.receiveOne(100 milliseconds)
|
||||
assert(msg.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GuidedControlTest2 extends ActorTest {
|
||||
"VehicleSpawnControlGuided" should {
|
||||
"guided (one)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
vehicle.Velocity = Vector3(1,1,1)
|
||||
val driver = Player(Avatar("", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
driver.VehicleSeated = vehicle.GUID
|
||||
val sendTo = TestProbe()
|
||||
val order = VehicleSpawnControl.Order(driver, vehicle, sendTo.ref)
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
pad.Railed = false //suppress certain events
|
||||
val guided = system.actorOf(Props(classOf[VehicleSpawnControlGuided], pad), "pad")
|
||||
|
||||
pad.Guide = List(AutoDriveControls.FirstGear())
|
||||
guided ! VehicleSpawnControl.Process.StartGuided(order)
|
||||
val msg1 = sendTo.receiveOne(100 milliseconds)
|
||||
assert(msg1.isInstanceOf[VehicleSpawnControlGuided.GuidedControl])
|
||||
assert(msg1.asInstanceOf[VehicleSpawnControlGuided.GuidedControl].command == AutoDriveControls.State.Drive)
|
||||
val msg2 = sendTo.receiveOne(200 milliseconds)
|
||||
assert(msg2.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GuidedControlTest3 extends ActorTest {
|
||||
"VehicleSpawnControlGuided" should {
|
||||
"guided (three)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
vehicle.Velocity = Vector3(1,1,1)
|
||||
val driver = Player(Avatar("", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
driver.VehicleSeated = vehicle.GUID
|
||||
val sendTo = TestProbe()
|
||||
val order = VehicleSpawnControl.Order(driver, vehicle, sendTo.ref)
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
pad.Railed = false //suppress certain events
|
||||
val guided = system.actorOf(Props(classOf[VehicleSpawnControlGuided], pad), "pad")
|
||||
|
||||
pad.Guide = List(
|
||||
AutoDriveControls.FirstGear(),
|
||||
AutoDriveControls.ForTime(1000L),
|
||||
AutoDriveControls.SecondGear()
|
||||
)
|
||||
guided ! VehicleSpawnControl.Process.StartGuided(order)
|
||||
val msg1 = sendTo.receiveOne(100 milliseconds)
|
||||
assert(msg1.isInstanceOf[VehicleSpawnControlGuided.GuidedControl])
|
||||
assert(msg1.asInstanceOf[VehicleSpawnControlGuided.GuidedControl].command == AutoDriveControls.State.Drive)
|
||||
val msg2 = sendTo.receiveOne(100 milliseconds)
|
||||
assert(msg2.isInstanceOf[VehicleSpawnControlGuided.GuidedControl])
|
||||
assert(msg2.asInstanceOf[VehicleSpawnControlGuided.GuidedControl].command == AutoDriveControls.State.Wait)
|
||||
sendTo.expectNoMsg(1000 milliseconds)
|
||||
val msg3 = sendTo.receiveOne(300 milliseconds)
|
||||
assert(msg3.isInstanceOf[VehicleSpawnControlGuided.GuidedControl])
|
||||
assert(msg3.asInstanceOf[VehicleSpawnControlGuided.GuidedControl].command == AutoDriveControls.State.Drive)
|
||||
val msg4 = sendTo.receiveOne(200 milliseconds)
|
||||
assert(msg4.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GuidedControlTest4 extends ActorTest {
|
||||
"VehicleSpawnControlGuided" should {
|
||||
"fail validation test" in {
|
||||
def validationFailure(vehicle : Vehicle) : Boolean = false
|
||||
|
||||
val vehicle = Vehicle(GlobalDefinitions.mediumtransport)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
vehicle.Velocity = Vector3(1,1,1)
|
||||
val driver = Player(Avatar("", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
driver.VehicleSeated = vehicle.GUID
|
||||
val sendTo = TestProbe()
|
||||
val order = VehicleSpawnControl.Order(driver, vehicle, sendTo.ref)
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
pad.Railed = false //suppress certain events
|
||||
val guided = system.actorOf(Props(classOf[VehicleSpawnControlGuided], pad), "pad")
|
||||
|
||||
pad.Guide = List(
|
||||
AutoDriveControls.FirstGear(),
|
||||
AutoDriveControls.CancelEarly(validationFailure),
|
||||
AutoDriveControls.SecondGear()
|
||||
)
|
||||
guided ! VehicleSpawnControl.Process.StartGuided(order)
|
||||
val msg1 = sendTo.receiveOne(100 milliseconds)
|
||||
assert(msg1.isInstanceOf[VehicleSpawnControlGuided.GuidedControl])
|
||||
assert(msg1.asInstanceOf[VehicleSpawnControlGuided.GuidedControl].command == AutoDriveControls.State.Drive)
|
||||
val msg2 = sendTo.receiveOne(200 milliseconds)
|
||||
assert(msg2.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,11 +9,11 @@ import net.psforever.objects.guid.TaskResolver
|
|||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.resourcesilo.{ResourceSilo, ResourceSiloControl, ResourceSiloDefinition}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.{PlanetSideGUID, UseItemMessage}
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
|
||||
import org.specs2.mutable.Specification
|
||||
import services.ServiceManager
|
||||
import services.{Service, ServiceManager}
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -103,24 +103,23 @@ class ResourceSiloControlUseTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlNtuWarningTest extends ActorTest {
|
||||
val serviceManager = ServiceManager.boot(system)
|
||||
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val probe = TestProbe()
|
||||
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe), "avatar")
|
||||
val zone = new Zone("nowhere", new ZoneMap("nowhere-map"), 0)
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
val obj = ResourceSilo()
|
||||
obj.GUID = PlanetSideGUID(1)
|
||||
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
|
||||
obj.Actor ! "startup"
|
||||
obj.Owner = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building, GlobalDefinitions.building)
|
||||
obj.Owner = bldg
|
||||
val zoneEvents = TestProbe("zone-events")
|
||||
|
||||
"Resource silo" should {
|
||||
"announce high ntu" in {
|
||||
expectNoMsg(1 seconds)
|
||||
assert(obj.LowNtuWarningOn == true)
|
||||
zone.AvatarEvents = zoneEvents.ref
|
||||
assert(obj.LowNtuWarningOn)
|
||||
obj.Actor ! ResourceSilo.LowNtuWarning(false)
|
||||
|
||||
val reply = probe.receiveOne(500 milliseconds)
|
||||
assert(obj.LowNtuWarningOn == false)
|
||||
val reply = zoneEvents.receiveOne(500 milliseconds)
|
||||
assert(!obj.LowNtuWarningOn)
|
||||
assert(reply.isInstanceOf[AvatarServiceMessage])
|
||||
assert(reply.asInstanceOf[AvatarServiceMessage].forChannel == "nowhere")
|
||||
assert(reply.asInstanceOf[AvatarServiceMessage]
|
||||
|
|
@ -136,29 +135,27 @@ class ResourceSiloControlNtuWarningTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlUpdate1Test extends ActorTest {
|
||||
val serviceManager = ServiceManager.boot(system)
|
||||
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val probe1 = TestProbe()
|
||||
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe1), "avatar")
|
||||
val zone = new Zone("nowhere", new ZoneMap("nowhere-map"), 0)
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
val obj = ResourceSilo()
|
||||
obj.GUID = PlanetSideGUID(1)
|
||||
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
|
||||
obj.Actor ! "startup"
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building, GlobalDefinitions.building)
|
||||
val probe2 = TestProbe()
|
||||
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
|
||||
obj.Owner = bldg
|
||||
val zoneEvents = TestProbe("zone-events")
|
||||
val buildingEvents = TestProbe("building-events")
|
||||
|
||||
"Resource silo" should {
|
||||
"update the charge level and capacitor display (report high ntu, power restored)" in {
|
||||
expectNoMsg(1 seconds)
|
||||
zone.AvatarEvents = zoneEvents.ref
|
||||
bldg.Actor = buildingEvents.ref
|
||||
|
||||
assert(obj.ChargeLevel == 0)
|
||||
assert(obj.CapacitorDisplay == 0)
|
||||
obj.Actor ! ResourceSilo.UpdateChargeLevel(305)
|
||||
|
||||
val reply1 = probe1.receiveOne(500 milliseconds)
|
||||
val reply2 = probe2.receiveOne(500 milliseconds)
|
||||
val reply1 = zoneEvents.receiveOne(500 milliseconds)
|
||||
val reply2 = buildingEvents.receiveOne(500 milliseconds)
|
||||
assert(obj.ChargeLevel == 305)
|
||||
assert(obj.CapacitorDisplay == 4)
|
||||
assert(reply1.isInstanceOf[AvatarServiceMessage])
|
||||
|
|
@ -174,7 +171,7 @@ class ResourceSiloControlUpdate1Test extends ActorTest {
|
|||
|
||||
assert(reply2.isInstanceOf[Building.SendMapUpdate])
|
||||
|
||||
val reply3 = probe1.receiveOne(500 milliseconds)
|
||||
val reply3 = zoneEvents.receiveOne(500 milliseconds)
|
||||
assert(reply3.isInstanceOf[AvatarServiceMessage])
|
||||
assert(reply3.asInstanceOf[AvatarServiceMessage].forChannel == "nowhere")
|
||||
assert(reply3.asInstanceOf[AvatarServiceMessage]
|
||||
|
|
@ -186,7 +183,7 @@ class ResourceSiloControlUpdate1Test extends ActorTest {
|
|||
assert(reply3.asInstanceOf[AvatarServiceMessage]
|
||||
.actionMessage.asInstanceOf[AvatarAction.PlanetsideAttribute].attribute_value == 0)
|
||||
|
||||
val reply4 = probe1.receiveOne(500 milliseconds)
|
||||
val reply4 = zoneEvents.receiveOne(500 milliseconds)
|
||||
assert(!obj.LowNtuWarningOn)
|
||||
assert(reply4.isInstanceOf[AvatarServiceMessage])
|
||||
assert(reply4.asInstanceOf[AvatarServiceMessage].forChannel == "nowhere")
|
||||
|
|
@ -203,33 +200,31 @@ class ResourceSiloControlUpdate1Test extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlUpdate2Test extends ActorTest {
|
||||
val serviceManager = ServiceManager.boot(system)
|
||||
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val probe1 = TestProbe()
|
||||
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe1), "avatar")
|
||||
val zone = new Zone("nowhere", new ZoneMap("nowhere-map"), 0)
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
val obj = ResourceSilo()
|
||||
obj.GUID = PlanetSideGUID(1)
|
||||
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
|
||||
obj.Actor ! "startup"
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building, GlobalDefinitions.building)
|
||||
val probe2 = TestProbe()
|
||||
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
|
||||
obj.Owner = bldg
|
||||
val zoneEvents = TestProbe("zone-events")
|
||||
val buildingEvents = TestProbe("building-events")
|
||||
|
||||
"Resource silo" should {
|
||||
"update the charge level and capacitor display (report good ntu)" in {
|
||||
expectNoMsg(1 seconds)
|
||||
zone.AvatarEvents = zoneEvents.ref
|
||||
bldg.Actor = buildingEvents.ref
|
||||
|
||||
obj.ChargeLevel = 100
|
||||
obj.CapacitorDisplay = 1
|
||||
obj.LowNtuWarningOn = true
|
||||
assert(obj.ChargeLevel == 100)
|
||||
assert(obj.CapacitorDisplay == 1)
|
||||
assert(obj.LowNtuWarningOn == true)
|
||||
assert(obj.LowNtuWarningOn)
|
||||
obj.Actor ! ResourceSilo.UpdateChargeLevel(105)
|
||||
|
||||
val reply1 = probe1.receiveOne(500 milliseconds)
|
||||
val reply2 = probe2.receiveOne(500 milliseconds)
|
||||
val reply1 = zoneEvents.receiveOne(500 milliseconds)
|
||||
val reply2 = buildingEvents.receiveOne(500 milliseconds)
|
||||
assert(obj.ChargeLevel == 205)
|
||||
assert(obj.CapacitorDisplay == 3)
|
||||
assert(reply1.isInstanceOf[AvatarServiceMessage])
|
||||
|
|
@ -245,8 +240,8 @@ class ResourceSiloControlUpdate2Test extends ActorTest {
|
|||
|
||||
assert(reply2.isInstanceOf[Building.SendMapUpdate])
|
||||
|
||||
val reply3 = probe1.receiveOne(500 milliseconds)
|
||||
assert(obj.LowNtuWarningOn == false)
|
||||
val reply3 = zoneEvents.receiveOne(500 milliseconds)
|
||||
assert(!obj.LowNtuWarningOn)
|
||||
assert(reply3.isInstanceOf[AvatarServiceMessage])
|
||||
assert(reply3.asInstanceOf[AvatarServiceMessage].forChannel == "nowhere")
|
||||
assert(reply3.asInstanceOf[AvatarServiceMessage]
|
||||
|
|
@ -262,43 +257,41 @@ class ResourceSiloControlUpdate2Test extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlNoUpdateTest extends ActorTest {
|
||||
val serviceManager = ServiceManager.boot(system)
|
||||
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val probe1 = TestProbe()
|
||||
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe1), "avatar")
|
||||
val zone = new Zone("nowhere", new ZoneMap("nowhere-map"), 0)
|
||||
val bldg = new Building(building_guid = 6, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
val obj = ResourceSilo()
|
||||
obj.GUID = PlanetSideGUID(1)
|
||||
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
|
||||
obj.Actor ! "startup"
|
||||
val bldg = new Building(building_guid = 6, map_id = 6, Zone.Nowhere, StructureType.Building, GlobalDefinitions.building)
|
||||
val probe2 = TestProbe()
|
||||
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
|
||||
obj.Owner = bldg
|
||||
val zoneEvents = TestProbe("zone-events")
|
||||
val buildingEvents = TestProbe("building-events")
|
||||
|
||||
"Resource silo" should {
|
||||
"update, but not sufficiently to change the capacitor display" in {
|
||||
expectNoMsg(1 seconds)
|
||||
zone.AvatarEvents = zoneEvents.ref
|
||||
bldg.Actor = buildingEvents.ref
|
||||
|
||||
obj.ChargeLevel = 250
|
||||
obj.CapacitorDisplay = 3
|
||||
obj.LowNtuWarningOn = false
|
||||
assert(obj.ChargeLevel == 250)
|
||||
assert(obj.CapacitorDisplay == 3)
|
||||
assert(obj.LowNtuWarningOn == false)
|
||||
assert(!obj.LowNtuWarningOn)
|
||||
obj.Actor ! ResourceSilo.UpdateChargeLevel(50)
|
||||
|
||||
expectNoMsg(500 milliseconds)
|
||||
probe1.expectNoMsg(500 milliseconds)
|
||||
probe2.expectNoMsg(500 milliseconds)
|
||||
zoneEvents.expectNoMsg(500 milliseconds)
|
||||
buildingEvents.expectNoMsg(500 milliseconds)
|
||||
assert(obj.ChargeLevel == 299 || obj.ChargeLevel == 300) // Just in case the capacitor level drops while waiting for the message check 299 & 300
|
||||
assert(obj.CapacitorDisplay == 3)
|
||||
assert(obj.LowNtuWarningOn == false)
|
||||
assert(!obj.LowNtuWarningOn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ResourceSiloTest {
|
||||
val player = Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
val player = Player(new Avatar(0L, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
|
||||
class ProbedAvatarService(probe : TestProbe) extends Actor {
|
||||
override def receive : Receive = {
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ package objects
|
|||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.serverobject.structures.StructureType
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterVoice, PlanetSideEmpire, Vector3}
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -27,14 +27,6 @@ class VehicleSpawnPadTest extends Specification {
|
|||
val obj = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
obj.Actor mustEqual ActorRef.noSender
|
||||
obj.Definition mustEqual GlobalDefinitions.mb_pad_creation
|
||||
obj.Railed mustEqual true
|
||||
}
|
||||
|
||||
"un-railed" in {
|
||||
val obj = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
obj.Railed mustEqual true
|
||||
obj.Railed = false
|
||||
obj.Railed mustEqual false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,264 +41,174 @@ class VehicleSpawnControl1Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl2aTest extends ActorTest {
|
||||
// This runs for a long time.
|
||||
class VehicleSpawnControl2Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"complete on a vehicle order (block a second one until the first is done and the spawn pad is cleared)" in {
|
||||
"complete a vehicle order" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
//we can recycle the vehicle and the player for each order
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe2 = new TestProbe(system, "second-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref) //first order
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe2.ref) //second order
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
val probe2Msg1 = probe2.receiveOne(100 milliseconds)
|
||||
assert(probe2Msg1.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe2Msg1.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Queue)
|
||||
assert(probe2Msg1.asInstanceOf[VehicleSpawnPad.PeriodicReminder].data.contains("2"))
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
|
||||
val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
|
||||
val probe3Msg3 = probe3.receiveOne(200 milliseconds)
|
||||
assert(probe3Msg3.isInstanceOf[VehicleSpawnPad.AttachToRails])
|
||||
|
||||
val probe1Msg1 = probe1.receiveOne(200 milliseconds)
|
||||
assert(probe1Msg1.isInstanceOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
val probe1Msg2 = probe1.receiveOne(200 milliseconds)
|
||||
assert(probe1Msg2.isInstanceOf[Mountable.MountMessages])
|
||||
val probe1Msg2Contents = probe1Msg2.asInstanceOf[Mountable.MountMessages]
|
||||
assert(probe1Msg2Contents.response.isInstanceOf[Mountable.CanMount])
|
||||
val probe1Msg3 = probe1.receiveOne(3 seconds)
|
||||
assert(probe1Msg3.isInstanceOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
|
||||
val probe3Msg4 = probe3.receiveOne(1 seconds)
|
||||
assert(probe3Msg4.isInstanceOf[VehicleSpawnPad.DetachFromRails])
|
||||
|
||||
val probe1Msg4 = probe1.receiveOne(1 seconds)
|
||||
assert(probe1Msg4.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
val probe1Msg5 = probe1.receiveOne(4 seconds)
|
||||
assert(probe1Msg5.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
|
||||
val probe1Msg6 = probe1.receiveOne(11 seconds)
|
||||
assert(probe1Msg6.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe1Msg6.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
val probe2Msg2 = probe2.receiveOne(100 milliseconds)
|
||||
assert(probe2Msg2.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe2Msg2.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
|
||||
//if we move the vehicle more than 25m away from the pad, we should receive a ResetSpawnPad, and a second ConcealPlayer message
|
||||
//that means that the first order has cleared and the spawn pad is now working on the second order successfully
|
||||
player.VehicleSeated = None //since shared between orders, is necessary
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).Occupant = player
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
//if we move the vehicle away from the pad, we should receive a ResetSpawnPad message
|
||||
//that means that the first order has cleared and the spawn pad is now waiting for additional orders
|
||||
vehicle.Position = Vector3(12,0,0)
|
||||
val probe3Msg5 = probe3.receiveOne(4 seconds)
|
||||
assert(probe3Msg5.isInstanceOf[VehicleSpawnPad.ResetSpawnPad])
|
||||
val probe3Msg6 = probe3.receiveOne(4 seconds)
|
||||
assert(probe3Msg6.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl2bTest extends ActorTest {
|
||||
// This runs for a long time.
|
||||
"VehicleSpawnControl" should {
|
||||
"complete on a vehicle order (railless)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
//we can recycle the vehicle and the player for each order
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe2 = new TestProbe(system, "second-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
pad.Railed = false
|
||||
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref) //first order
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe2.ref) //second order
|
||||
|
||||
val probe2Msg1 = probe2.receiveOne(100 milliseconds)
|
||||
assert(probe2Msg1.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe2Msg1.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Queue)
|
||||
assert(probe2Msg1.asInstanceOf[VehicleSpawnPad.PeriodicReminder].data.contains("2"))
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
|
||||
val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
|
||||
val probe1Msg1 = probe1.receiveOne(200 milliseconds)
|
||||
assert(probe1Msg1.isInstanceOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
val probe1Msg2 = probe1.receiveOne(200 milliseconds)
|
||||
assert(probe1Msg2.isInstanceOf[Mountable.MountMessages])
|
||||
val probe1Msg2Contents = probe1Msg2.asInstanceOf[Mountable.MountMessages]
|
||||
assert(probe1Msg2Contents.response.isInstanceOf[Mountable.CanMount])
|
||||
val probe1Msg3 = probe1.receiveOne(4 seconds)
|
||||
assert(probe1Msg3.isInstanceOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
|
||||
val probe1Msg4 = probe1.receiveOne(1 seconds)
|
||||
assert(probe1Msg4.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
val probe1Msg5 = probe1.receiveOne(4 seconds)
|
||||
assert(probe1Msg5.isInstanceOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
|
||||
val probe1Msg6 = probe1.receiveOne(11 seconds)
|
||||
assert(probe1Msg6.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe1Msg6.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
val probe2Msg2 = probe2.receiveOne(100 milliseconds)
|
||||
assert(probe2Msg2.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe2Msg2.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
|
||||
//if we move the vehicle more than 10m away from the pad, we should receive a second ConcealPlayer message
|
||||
//that means that the first order has cleared and the spawn pad is now working on the second order successfully
|
||||
player.VehicleSeated = None //since shared between orders, is necessary
|
||||
vehicle.Position = Vector3(12,0,0)
|
||||
val probe3Msg6 = probe3.receiveOne(10 seconds)
|
||||
assert(probe3Msg6.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ResetSpawnPad])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl3Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"player is on wrong continent before vehicle can partially load; vehicle is cleaned up" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
player.Continent = "problem" //problem
|
||||
|
||||
assert(vehicle.HasGUID)
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref)
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.RevealPlayer])
|
||||
probe3.expectNoMsg(5 seconds)
|
||||
assert(!vehicle.HasGUID) //vehicle has been unregistered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl4Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"the player is on wrong continent when the vehicle tries to load; vehicle is cleaned up" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref)
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
player.Continent = "problem" //problem
|
||||
assert(vehicle.HasGUID)
|
||||
|
||||
val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.RevealPlayer])
|
||||
probe3.expectNoMsg(5 seconds)
|
||||
assert(!vehicle.HasGUID) //vehicle has been unregistered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//class VehicleSpawnControl5aTest extends ActorTest() {
|
||||
// "VehicleSpawnControl" should {
|
||||
// "the vehicle is destroyed before being fully loaded; the vehicle is cleaned up" in {
|
||||
// val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
// //we can recycle the vehicle and the player for each order
|
||||
// val probe1 = new TestProbe(system, "first-order")
|
||||
// val probe3 = new TestProbe(system, "zone-events")
|
||||
// zone.VehicleEvents = probe3.ref
|
||||
//
|
||||
// pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref)
|
||||
//
|
||||
// val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
// assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
//
|
||||
// val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
// assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
// vehicle.Health = 0 //problem
|
||||
//
|
||||
// val probe3Msg3 = probe3.receiveOne(3 seconds)
|
||||
// assert(probe3Msg3.isInstanceOf[VehicleSpawnPad.DisposeVehicle])
|
||||
// val probe3Msg4 = probe3.receiveOne(100 milliseconds)
|
||||
// assert(probe3Msg4.isInstanceOf[VehicleSpawnPad.RevealPlayer])
|
||||
// //note: the vehicle will not be unregistered by this logic alone
|
||||
// //since LoadVehicle should introduce it into the game world properly, it has to be handled properly
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
class VehicleSpawnControl5Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"player dies right after vehicle partially loads; the vehicle spawns and blocks the pad" in {
|
||||
"block the second vehicle order until the first is completed" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
//we can recycle the vehicle and the player for each order
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
val player2 = Player(Avatar("test2", player.Faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
player2.GUID = PlanetSideGUID(11)
|
||||
player2.Continent = zone.Id
|
||||
player2.Spawn
|
||||
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref)
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //first order
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player2, vehicle) //second order (vehicle shared)
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
assert(probe.receiveOne(1 seconds) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Queue, _) => true
|
||||
case _ => false
|
||||
})
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).Occupant = player
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
player.Die //problem
|
||||
|
||||
val probe3Msg3 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg3.isInstanceOf[VehicleSpawnPad.AttachToRails])
|
||||
val probe3Msg4 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg4.isInstanceOf[VehicleSpawnPad.DetachFromRails])
|
||||
|
||||
val probe3Msg5 = probe3.receiveOne(1 seconds)
|
||||
assert(probe3Msg5.isInstanceOf[VehicleSpawnPad.RevealPlayer])
|
||||
|
||||
val probe1Msg = probe1.receiveOne(12 seconds)
|
||||
assert(probe1Msg.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe1Msg.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
//if we move the vehicle away from the pad, we should receive a second ConcealPlayer message
|
||||
//that means that the first order has cleared and the spawn pad is now working on the second order successfully
|
||||
player.VehicleSeated = None //since shared between orders, as necessary
|
||||
vehicle.Seats(0).Occupant = None
|
||||
vehicle.Position = Vector3(12,0,0)
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ResetSpawnPad])
|
||||
probe.expectMsgClass(3 seconds, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl6Test extends ActorTest {
|
||||
class VehicleSpawnControl4Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"the player can not sit in vehicle; vehicle spawns and blocks the pad" in {
|
||||
"clean up the vehicle if the driver-to-be is on the wrong continent" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
//we can recycle the vehicle and the player for each order
|
||||
val probe1 = new TestProbe(system, "first-order")
|
||||
val probe3 = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe3.ref
|
||||
|
||||
pad.Actor.tell(VehicleSpawnPad.VehicleOrder(player, vehicle), probe1.ref)
|
||||
|
||||
val probe3Msg1 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg1.isInstanceOf[VehicleSpawnPad.ConcealPlayer])
|
||||
|
||||
val probe3Msg2 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
|
||||
val probe3Msg3 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg3.isInstanceOf[VehicleSpawnPad.AttachToRails])
|
||||
|
||||
val probe1Msg1 = probe1.receiveOne(200 milliseconds)
|
||||
assert(probe1Msg1.isInstanceOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
player.Continent = "problem" //problem
|
||||
probe1.receiveOne(200 milliseconds) //Mountable.MountMessage
|
||||
|
||||
val probe3Msg4 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg4.isInstanceOf[VehicleSpawnPad.DetachFromRails])
|
||||
val probe3Msg5 = probe3.receiveOne(3 seconds)
|
||||
assert(probe3Msg5.isInstanceOf[VehicleSpawnPad.RevealPlayer])
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
val probe1Msg3 = probe1.receiveOne(12 seconds)
|
||||
assert(probe1Msg3.isInstanceOf[VehicleSpawnPad.PeriodicReminder])
|
||||
assert(probe1Msg3.asInstanceOf[VehicleSpawnPad.PeriodicReminder].reason == VehicleSpawnPad.Reminders.Blocked)
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DisposeVehicle])
|
||||
probe.expectNoMsg(5 seconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl5Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a destroyed vehicle on the spawn pad (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
vehicle.Health = 0 //problem
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_,_,_,_,_)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl6Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a vehicle on the spawn pad if driver is unfit to drive (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
player.Die
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_,_,_,_,_)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl7Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a vehicle on the spawn pad if driver is unfit to drive (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
player.ExoSuit = ExoSuitType.MAX
|
||||
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_,_,_,_,_)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,15 +226,19 @@ object VehicleSpawnPadControlTest {
|
|||
import net.psforever.objects.Tool
|
||||
import net.psforever.types.CharacterGender
|
||||
|
||||
val zone = new Zone("test-zone", map, 0) { override def SetupNumberPools() = { } }
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
||||
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
||||
guid.AddPool("test-pool", (0 to 2).toList)
|
||||
guid.register(vehicle, "test-pool")
|
||||
guid.register(weapon, "test-pool")
|
||||
guid.register(weapon.AmmoSlot.Box, "test-pool")
|
||||
zone.GUID(guid)
|
||||
val zone = new Zone("test-zone", map, 0) {
|
||||
override def SetupNumberPools() = {
|
||||
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
||||
guid.AddPool("test-pool", (0 to 2).toList)
|
||||
//do not do this under normal conditions
|
||||
guid.register(vehicle, "test-pool")
|
||||
guid.register(weapon, "test-pool")
|
||||
guid.register(weapon.AmmoSlot.Box, "test-pool")
|
||||
GUID(guid)
|
||||
}
|
||||
}
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), s"test-zone-${System.nanoTime()}")
|
||||
zone.Actor ! Zone.Init()
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), s"vehicle-control-${System.nanoTime()}")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package objects.terminal
|
|||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.guid.TaskResolver
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, ProximityTerminalControl, ProximityUnit, Terminal}
|
||||
|
|
@ -13,8 +12,8 @@ import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
|
|||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
|
||||
import org.specs2.mutable.Specification
|
||||
import services.{Service, ServiceManager}
|
||||
import services.local.{LocalResponse, LocalService, LocalServiceResponse}
|
||||
import services.Service
|
||||
import services.local.LocalService
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -96,19 +95,14 @@ class ProximityTest extends Specification {
|
|||
class ProximityTerminalControlStartTest extends ActorTest {
|
||||
"ProximityTerminalControl" should {
|
||||
//setup
|
||||
val probe = new TestProbe(system)
|
||||
val service = ServiceManager.boot(system)
|
||||
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
|
||||
override def SetupNumberPools() = {
|
||||
AddPool("dynamic", 1 to 10)
|
||||
}
|
||||
}
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility, GlobalDefinitions.building) {
|
||||
Amenities = terminal
|
||||
Faction = PlanetSideEmpire.VS
|
||||
|
|
@ -122,17 +116,18 @@ class ProximityTerminalControlStartTest extends ActorTest {
|
|||
terminal.GUID = PlanetSideGUID(2)
|
||||
terminal.Actor ! Service.Startup()
|
||||
expectNoMsg(500 milliseconds) //spacer
|
||||
val probe1 = new TestProbe(system, "local-events")
|
||||
val probe2 = new TestProbe(system, "target-callback")
|
||||
zone.LocalEvents = probe1.ref
|
||||
|
||||
"send out a start message" in {
|
||||
assert(terminal.NumberUsers == 0)
|
||||
assert(terminal.Owner.Continent.equals("test"))
|
||||
terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
|
||||
|
||||
val msg = probe.receiveOne(500 milliseconds)
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
||||
probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect])
|
||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||
assert(terminal.NumberUsers == 1)
|
||||
assert(msg.isInstanceOf[LocalServiceResponse])
|
||||
val resp = msg.asInstanceOf[LocalServiceResponse]
|
||||
assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -140,50 +135,50 @@ class ProximityTerminalControlStartTest extends ActorTest {
|
|||
class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
||||
"ProximityTerminalControl" should {
|
||||
//setup
|
||||
val probe = new TestProbe(system)
|
||||
val service = ServiceManager.boot(system)
|
||||
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
|
||||
override def SetupNumberPools() = {
|
||||
AddPool("dynamic", 1 to 10)
|
||||
}
|
||||
}
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility, GlobalDefinitions.building) {
|
||||
Amenities = terminal
|
||||
Faction = PlanetSideEmpire.VS
|
||||
}
|
||||
|
||||
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar.Continent = "test"
|
||||
avatar.Spawn
|
||||
avatar.Health = 50
|
||||
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar2.Continent = "test"
|
||||
avatar2.Spawn
|
||||
avatar2.Health = 50
|
||||
|
||||
avatar.GUID = PlanetSideGUID(1)
|
||||
terminal.GUID = PlanetSideGUID(2)
|
||||
avatar.GUID = PlanetSideGUID(2)
|
||||
terminal.GUID = PlanetSideGUID(3)
|
||||
terminal.Actor ! Service.Startup()
|
||||
expectNoMsg(500 milliseconds) //spacer
|
||||
val probe1 = new TestProbe(system, "local-events")
|
||||
val probe2 = new TestProbe(system, "target-callback-1")
|
||||
val probe3 = new TestProbe(system, "target-callback-2")
|
||||
zone.LocalEvents = probe1.ref
|
||||
|
||||
"will not send out a start message if not the first user" in {
|
||||
"not send out a start message if not the first user" in {
|
||||
assert(terminal.NumberUsers == 0)
|
||||
assert(terminal.Owner.Continent.equals("test"))
|
||||
|
||||
terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
|
||||
val msg = probe.receiveOne(500 milliseconds)
|
||||
assert(terminal.NumberUsers == 1)
|
||||
assert(msg.isInstanceOf[LocalServiceResponse])
|
||||
val resp = msg.asInstanceOf[LocalServiceResponse]
|
||||
assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
||||
probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect])
|
||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||
|
||||
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar2.Continent = "test"
|
||||
avatar2.Spawn
|
||||
avatar2.Health = 50
|
||||
terminal.Actor ! CommonMessages.Use(avatar2, Some(avatar2))
|
||||
probe.expectNoMsg(500 milliseconds)
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref)
|
||||
probe1.expectNoMsg(1 second)
|
||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||
probe3.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||
assert(terminal.NumberUsers == 2)
|
||||
}
|
||||
}
|
||||
|
|
@ -192,19 +187,14 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
|||
class ProximityTerminalControlStopTest extends ActorTest {
|
||||
"ProximityTerminalControl" should {
|
||||
//setup
|
||||
val probe = new TestProbe(system)
|
||||
val service = ServiceManager.boot(system)
|
||||
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
|
||||
override def SetupNumberPools() = {
|
||||
AddPool("dynamic", 1 to 10)
|
||||
}
|
||||
}
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility, GlobalDefinitions.building) {
|
||||
Amenities = terminal
|
||||
Faction = PlanetSideEmpire.VS
|
||||
|
|
@ -218,24 +208,21 @@ class ProximityTerminalControlStopTest extends ActorTest {
|
|||
terminal.GUID = PlanetSideGUID(2)
|
||||
terminal.Actor ! Service.Startup()
|
||||
expectNoMsg(500 milliseconds) //spacer
|
||||
val probe1 = new TestProbe(system, "local-events")
|
||||
val probe2 = new TestProbe(system, "target-callback-1")
|
||||
zone.LocalEvents = probe1.ref
|
||||
|
||||
"send out a stop message" in {
|
||||
assert(terminal.NumberUsers == 0)
|
||||
assert(terminal.Owner.Continent.equals("test"))
|
||||
|
||||
terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
|
||||
val msg1 = probe.receiveOne(500 milliseconds)
|
||||
assert(terminal.NumberUsers == 1)
|
||||
assert(msg1.isInstanceOf[LocalServiceResponse])
|
||||
val resp1 = msg1.asInstanceOf[LocalServiceResponse]
|
||||
assert(resp1.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
||||
probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect])
|
||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||
|
||||
terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
|
||||
val msg2 = probe.receiveWhile(500 milliseconds) {
|
||||
case LocalServiceResponse(_, _, replyMessage) => replyMessage
|
||||
}
|
||||
probe1.expectMsgClass(1 second, classOf[Terminal.StopProximityEffect])
|
||||
assert(terminal.NumberUsers == 0)
|
||||
assert(msg2.last == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,58 +230,59 @@ class ProximityTerminalControlStopTest extends ActorTest {
|
|||
class ProximityTerminalControlNotStopTest extends ActorTest {
|
||||
"ProximityTerminalControl" should {
|
||||
//setup
|
||||
val probe = new TestProbe(system)
|
||||
val service = ServiceManager.boot(system)
|
||||
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
|
||||
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
|
||||
override def SetupNumberPools() = {
|
||||
AddPool("dynamic", 1 to 10)
|
||||
}
|
||||
}
|
||||
val probe = new TestProbe(system)
|
||||
zone.LocalEvents = probe.ref
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
|
||||
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility, GlobalDefinitions.building) {
|
||||
Amenities = terminal
|
||||
Faction = PlanetSideEmpire.VS
|
||||
}
|
||||
|
||||
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar.Continent = "test"
|
||||
avatar.Spawn
|
||||
avatar.Health = 50
|
||||
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar2.Continent = "test"
|
||||
avatar2.Spawn
|
||||
avatar2.Health = 50
|
||||
|
||||
avatar.GUID = PlanetSideGUID(1)
|
||||
terminal.GUID = PlanetSideGUID(2)
|
||||
avatar.GUID = PlanetSideGUID(2)
|
||||
terminal.GUID = PlanetSideGUID(3)
|
||||
terminal.Actor ! Service.Startup()
|
||||
expectNoMsg(500 milliseconds) //spacer
|
||||
val probe1 = new TestProbe(system, "local-events")
|
||||
val probe2 = new TestProbe(system, "target-callback-1")
|
||||
val probe3 = new TestProbe(system, "target-callback-2")
|
||||
zone.LocalEvents = probe1.ref
|
||||
|
||||
"will not send out one stop message until last user" in {
|
||||
assert(terminal.NumberUsers == 0)
|
||||
assert(terminal.Owner.Continent.equals("test"))
|
||||
|
||||
terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
|
||||
val msg = probe.receiveOne(500 milliseconds)
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
||||
probe1.expectMsgClass(100 millisecond, classOf[Terminal.StartProximityEffect])
|
||||
assert(terminal.NumberUsers == 1)
|
||||
assert(msg.isInstanceOf[LocalServiceResponse])
|
||||
val resp = msg.asInstanceOf[LocalServiceResponse]
|
||||
assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
|
||||
|
||||
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
avatar2.Continent = "test"
|
||||
avatar2.Spawn
|
||||
avatar2.Health = 50
|
||||
terminal.Actor ! CommonMessages.Use(avatar2, Some(avatar2))
|
||||
probe.expectNoMsg(500 milliseconds)
|
||||
terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref)
|
||||
probe1.expectNoMsg(100 millisecond)
|
||||
assert(terminal.NumberUsers == 2)
|
||||
|
||||
terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
|
||||
val msg2 = probe.receiveWhile(500 milliseconds) {
|
||||
case LocalServiceResponse(_, _, replyMessage) => replyMessage
|
||||
}
|
||||
probe1.expectNoMsg(100 millisecond)
|
||||
assert(terminal.NumberUsers == 1)
|
||||
assert(!msg2.contains(LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), false)))
|
||||
|
||||
terminal.Actor ! CommonMessages.Unuse(avatar2, Some(avatar2))
|
||||
probe1.expectMsgClass(100 millisecond, classOf[Terminal.StopProximityEffect])
|
||||
assert(terminal.NumberUsers == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +290,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest {
|
|||
object ProximityTest {
|
||||
class SampleTerminal extends Terminal(GlobalDefinitions.dropship_vehicle_terminal) with ProximityUnit
|
||||
|
||||
class ProbedLocalService(probe : TestProbe) extends LocalService {
|
||||
class ProbedLocalService(probe : TestProbe, zone : Zone) extends LocalService(zone) {
|
||||
self.tell(Service.Join("test"), probe.ref)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class AvatarService1Test extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"construct" in {
|
||||
ServiceManager.boot(system)
|
||||
system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ class AvatarService2Test extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ class AvatarService3Test extends ActorTest {
|
|||
"AvatarService" should {
|
||||
ServiceManager.boot(system)
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
|
|
@ -52,7 +52,7 @@ class AvatarService4Test extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
|
|
@ -64,7 +64,7 @@ class AvatarService5Test extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass an unhandled message" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMsg()
|
||||
|
|
@ -76,7 +76,7 @@ class ArmorChangedTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ArmorChanged" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ArmorChanged(PlanetSideGUID(10), ExoSuitType.Reinforced, 0))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ArmorChanged(ExoSuitType.Reinforced, 0)))
|
||||
|
|
@ -88,7 +88,7 @@ class ConcealPlayerTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ConcealPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ConcealPlayer(PlanetSideGUID(10)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ConcealPlayer()))
|
||||
|
|
@ -97,11 +97,8 @@ class ConcealPlayerTest extends ActorTest {
|
|||
}
|
||||
|
||||
class EquipmentInHandTest extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "release-test-service")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0)
|
||||
val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver")
|
||||
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
|
|
@ -123,8 +120,8 @@ class EquipmentInHandTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DeployItemTest extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "deploy-item-test-service")
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "deploy-item-test-service")
|
||||
val objDef = GlobalDefinitions.motionalarmsensor
|
||||
val obj = new SensorDeployable(objDef)
|
||||
obj.Position = Vector3(1,2,3)
|
||||
|
|
@ -146,13 +143,8 @@ class DeployItemTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DroptItemTest extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "release-test-service")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0)
|
||||
val taskResolver = system.actorOf(Props[TaskResolver], "drop-item-test-resolver")
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-item-test-zone")
|
||||
zone.Actor ! Zone.Init()
|
||||
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.Position = Vector3(1,2,3)
|
||||
|
|
@ -171,7 +163,7 @@ class DroptItemTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass DropItem" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.DropItem(PlanetSideGUID(10), tool, zone))
|
||||
service ! AvatarServiceMessage("test", AvatarAction.DropItem(PlanetSideGUID(10), tool, Zone.Nowhere))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.DropItem(pkt)))
|
||||
}
|
||||
}
|
||||
|
|
@ -191,7 +183,7 @@ class LoadPlayerTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass LoadPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
//no parent data
|
||||
service ! AvatarServiceMessage("test", AvatarAction.LoadPlayer(
|
||||
|
|
@ -211,7 +203,7 @@ class ObjectDeleteTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ObjectDelete" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 0)))
|
||||
|
|
@ -226,7 +218,7 @@ class ObjectHeldTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ObjectHeld" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectHeld(PlanetSideGUID(10), 1))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectHeld(1)))
|
||||
|
|
@ -238,7 +230,7 @@ class PutDownFDUTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass PutDownFDU" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PutDownFDU(PlanetSideGUID(10))))
|
||||
|
|
@ -250,7 +242,7 @@ class PlanetsideAttributeTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass PlanetsideAttribute" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PlanetsideAttribute(5, 1200L)))
|
||||
|
|
@ -264,7 +256,7 @@ class PlayerStateTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass PlayerState" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PlayerState(PlanetSideGUID(10), Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 61.875f, 351.5625f, 0.0f, 136, false, false, false, false, false, false))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PlayerState(Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 61.875f, 351.5625f, 0.0f, 136, false, false, false, false, false, false)))
|
||||
|
|
@ -290,7 +282,7 @@ class PickupItemATest extends ActorTest {
|
|||
|
||||
"pass PickUpItem as EquipmentInHand (visible pistol slot)" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PickupItem(PlanetSideGUID(10), Zone.Nowhere, obj, 0, tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(pkt)))
|
||||
|
|
@ -304,7 +296,7 @@ class PickupItemBTest extends ActorTest {
|
|||
|
||||
"pass PickUpItem as ObjectDelete (not visible inventory space)" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PickupItem(PlanetSideGUID(10), Zone.Nowhere, obj, 6, tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(tool.GUID, 0)))
|
||||
|
|
@ -315,7 +307,7 @@ class ReloadTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass Reload" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Reload(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.Reload(PlanetSideGUID(40))))
|
||||
|
|
@ -330,7 +322,7 @@ class ChangeAmmoTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ChangeAmmo" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeAmmo(PlanetSideGUID(10), PlanetSideGUID(40), 0, PlanetSideGUID(40), ammoDef.ObjectId, PlanetSideGUID(41), ammoDef.Packet.ConstructorData(ammoBox).get))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeAmmo(PlanetSideGUID(40), 0, PlanetSideGUID(40), ammoDef.ObjectId, PlanetSideGUID(41), ammoDef.Packet.ConstructorData(ammoBox).get)))
|
||||
|
|
@ -345,7 +337,7 @@ class ChangeFireModeTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ChangeFireMode" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireMode(PlanetSideGUID(10), PlanetSideGUID(40), 0))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireMode(PlanetSideGUID(40), 0)))
|
||||
|
|
@ -357,7 +349,7 @@ class ChangeFireStateStartTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ChangeFireState_Start" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Start(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireState_Start(PlanetSideGUID(40))))
|
||||
|
|
@ -369,7 +361,7 @@ class ChangeFireStateStopTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass ChangeFireState_Stop" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Stop(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireState_Stop(PlanetSideGUID(40))))
|
||||
|
|
@ -387,7 +379,7 @@ class DamageTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass Damage" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Damage(PlanetSideGUID(10), player, test_func_ref))
|
||||
val msg = receiveOne(1 seconds)
|
||||
|
|
@ -408,7 +400,7 @@ class WeaponDryFireTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass WeaponDryFire" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.WeaponDryFire(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.WeaponDryFire(PlanetSideGUID(40))))
|
||||
|
|
@ -422,7 +414,7 @@ class AvatarStowEquipmentTest extends ActorTest {
|
|||
"AvatarService" should {
|
||||
"pass StowEquipment" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.StowEquipment(PlanetSideGUID(11), 2, tool)))
|
||||
|
|
@ -448,8 +440,8 @@ Even with all this work, the tests have a high chance of failure just due to bei
|
|||
*/
|
||||
class AvatarReleaseTest extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "release-test-service")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } }
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver")
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone")
|
||||
zone.Actor ! Zone.Init()
|
||||
|
|
@ -497,8 +489,8 @@ class AvatarReleaseTest extends ActorTest {
|
|||
|
||||
class AvatarReleaseEarly1Test extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "release-test-service")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } }
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver")
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone")
|
||||
zone.Actor ! Zone.Init()
|
||||
|
|
@ -547,8 +539,8 @@ class AvatarReleaseEarly1Test extends ActorTest {
|
|||
|
||||
class AvatarReleaseEarly2Test extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val service = system.actorOf(Props[AvatarService], "release-test-service")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) } }
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver], "release-test-resolver")
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "release-test-zone")
|
||||
zone.Actor ! Zone.Init()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import base.ActorTest
|
|||
import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import services.{Service, ServiceManager}
|
||||
|
|
@ -16,7 +17,7 @@ class LocalService1Test extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"construct" in {
|
||||
system.actorOf(Props[LocalService], "l_service")
|
||||
system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +28,7 @@ class LocalService2Test extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
|
|
@ -39,7 +40,7 @@ class LocalService3Test extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
|
|
@ -52,7 +53,7 @@ class LocalService4Test extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
|
|
@ -65,7 +66,7 @@ class LocalService5Test extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass an unhandled message" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMsg()
|
||||
|
|
@ -79,7 +80,7 @@ class AlertDestroyDeployableTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass AlertDestroyDeployable" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.AlertDestroyDeployable(PlanetSideGUID(10), obj))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), LocalResponse.AlertDestroyDeployable(obj)))
|
||||
|
|
@ -92,7 +93,7 @@ class DeployableMapIconTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass DeployableMapIcon" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test",
|
||||
LocalAction.DeployableMapIcon(
|
||||
|
|
@ -116,7 +117,7 @@ class DoorClosesTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass DoorCloses" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.DoorCloses(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.DoorCloses(PlanetSideGUID(40))))
|
||||
|
|
@ -134,7 +135,7 @@ class HackClearTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass HackClear" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.HackClear(PlanetSideGUID(10), obj, 0L, 1000L))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.HackClear(PlanetSideGUID(40), 0L, 1000L)))
|
||||
|
|
@ -144,7 +145,7 @@ class HackClearTest extends ActorTest {
|
|||
|
||||
class ProximityTerminalEffectOnTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.GUID = PlanetSideGUID(1)
|
||||
|
||||
|
|
@ -159,7 +160,7 @@ class ProximityTerminalEffectOnTest extends ActorTest {
|
|||
|
||||
class ProximityTerminalEffectOffTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
||||
terminal.GUID = PlanetSideGUID(1)
|
||||
|
||||
|
|
@ -177,7 +178,7 @@ class RouterTelepadTransportTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass RouterTelepadTransport" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.RouterTelepadTransport(PlanetSideGUID(10), PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13)))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.RouterTelepadTransport(PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13))))
|
||||
|
|
@ -191,7 +192,7 @@ class SetEmpireTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass SetEmpire" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), LocalResponse.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR)))
|
||||
|
|
@ -205,7 +206,7 @@ class ToggleTeleportSystemTest extends ActorTest {
|
|||
"LocalService" should {
|
||||
"pass ToggleTeleportSystem" in {
|
||||
val router = Vehicle(GlobalDefinitions.router)
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.ToggleTeleportSystem(PlanetSideGUID(10), router, None))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.ToggleTeleportSystem(router, None)))
|
||||
|
|
@ -218,7 +219,7 @@ class TriggerEffectTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass TriggerEffect (1)" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.TriggerEffect(PlanetSideGUID(10), "on", PlanetSideGUID(40)))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.TriggerEffect(PlanetSideGUID(40), "on", None, None)))
|
||||
|
|
@ -231,7 +232,7 @@ class TriggerEffectInfoTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass TriggerEffect (2)" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.TriggerEffectInfo(PlanetSideGUID(10), "on", PlanetSideGUID(40), true, 1000))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.TriggerEffect(PlanetSideGUID(40), "on", Some(TriggeredEffect(true, 1000)), None)))
|
||||
|
|
@ -244,7 +245,7 @@ class TriggerEffectLocationTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass TriggerEffect (3)" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.TriggerEffectLocation(PlanetSideGUID(10), "spawn_object_failed_effect", Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f)))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.TriggerEffect(PlanetSideGUID(0), "spawn_object_failed_effect", None, Some(TriggeredEffectLocation(Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f))))))
|
||||
|
|
@ -258,7 +259,7 @@ class TriggerSoundTest extends ActorTest {
|
|||
|
||||
"LocalService" should {
|
||||
"pass TriggerSound" in {
|
||||
val service = system.actorOf(Props[LocalService], "l_service")
|
||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
||||
service ! Service.Join("test")
|
||||
service ! LocalServiceMessage("test", LocalAction.TriggerSound(PlanetSideGUID(10), TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f))
|
||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f)))
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package service
|
|||
import akka.actor.Props
|
||||
import base.ActorTest
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types._
|
||||
import services.{Service, ServiceManager}
|
||||
|
|
@ -14,7 +15,7 @@ class VehicleService1Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"construct" in {
|
||||
system.actorOf(Props[VehicleService], "v-service")
|
||||
system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +26,7 @@ class VehicleService2Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
|
|
@ -37,7 +38,7 @@ class VehicleService3Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
|
|
@ -50,7 +51,7 @@ class VehicleService4Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"subscribe" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
|
|
@ -63,7 +64,7 @@ class VehicleService5Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass an unhandled message" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMsg()
|
||||
|
|
@ -76,7 +77,7 @@ class OwnershipTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass Awareness" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.Ownership(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.Ownership(PlanetSideGUID(11))))
|
||||
|
|
@ -89,7 +90,7 @@ class ChildObjectStateTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass ChildObjectState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -102,7 +103,7 @@ class DeployRequestTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass DeployRequest" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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))))
|
||||
|
|
@ -115,7 +116,7 @@ class DismountVehicleTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass DismountVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.DismountVehicle(PlanetSideGUID(10), BailType.Normal, false))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.DismountVehicle(BailType.Normal, false)))
|
||||
|
|
@ -131,7 +132,7 @@ class InventoryStateTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass InventoryState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -147,7 +148,7 @@ class InventoryState2Test extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass InventoryState2" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.InventoryState2(PlanetSideGUID(10), PlanetSideGUID(11), PlanetSideGUID(12), 13))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13)))
|
||||
|
|
@ -160,7 +161,7 @@ class KickPassengerTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass KickPassenger" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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))))
|
||||
|
|
@ -175,7 +176,7 @@ class LoadVehicleTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass LoadVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -188,7 +189,7 @@ class MountVehicleTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass MountVehicle" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -201,7 +202,7 @@ class SeatPermissionsTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass SeatPermissions" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -219,7 +220,7 @@ class StowEquipmentTest extends ActorTest {
|
|||
|
||||
"StowEquipment" should {
|
||||
"pass StowEquipment" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -232,7 +233,7 @@ class UnstowEquipmentTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass UnstowEquipment" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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))))
|
||||
|
|
@ -245,7 +246,7 @@ class VehicleStateTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass VehicleState" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "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)))
|
||||
|
|
@ -258,7 +259,7 @@ class TransferPassengerChannelTest extends ActorTest {
|
|||
|
||||
"VehicleService" should {
|
||||
"pass TransferPassengerChannel" in {
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
|
||||
val fury = Vehicle(GlobalDefinitions.fury)
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.TransferPassengerChannel(PlanetSideGUID(10), "old_channel", "new_channel", fury))
|
||||
|
|
@ -267,18 +268,18 @@ class TransferPassengerChannelTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class TransferPassengerTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
"VehicleService" should {
|
||||
"pass TransferPassenger" in {
|
||||
val fury = Vehicle(GlobalDefinitions.fury)
|
||||
val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
service ! Service.Join("test")
|
||||
service ! VehicleServiceMessage("test", VehicleAction.TransferPassenger(PlanetSideGUID(10), "temp_channel", fury, PlanetSideGUID(11)))
|
||||
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.TransferPassenger("temp_channel", fury, PlanetSideGUID(11))))
|
||||
}
|
||||
}
|
||||
}
|
||||
//class TransferPassengerTest extends ActorTest {
|
||||
// ServiceManager.boot(system)
|
||||
// "VehicleService" should {
|
||||
// "pass TransferPassenger" in {
|
||||
// val fury = Vehicle(GlobalDefinitions.fury)
|
||||
// val service = system.actorOf(Props[VehicleService], "v-service")
|
||||
// service ! Service.Join("test")
|
||||
// service ! VehicleServiceMessage("test", VehicleAction.TransferPassenger(PlanetSideGUID(10), "temp_channel", fury, PlanetSideGUID(11)))
|
||||
// expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.TransferPassenger("temp_channel", fury, PlanetSideGUID(11))))
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
object VehicleServiceTest {
|
||||
//decoy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue