originally just implemented drive-away speeds and timings for boarding vehicles manually; then attempted a trick where vehicles would be moved up out of the trench manually; finally, discovered how spawn platform rails work and how to find their guids easily and incorporated a nearly fully-functional vehicle spawn system(!); added examples of the 'railless' spawn pads to the East and Southeast of home3 HART C

This commit is contained in:
FateJH 2018-04-13 23:10:52 -04:00
parent fde49773cd
commit c87273c351
16 changed files with 314 additions and 90 deletions

View file

@ -845,6 +845,20 @@ object GlobalDefinitions {
}
}
/**
* Using the definition for a piece of `Equipment` determine whether it can fly.
* @param vdef the `VehicleDefinition` of the vehicle
* @return `true`, if it is; `false`, otherwise
*/
def isFlightVehicle(vdef : VehicleDefinition) : Boolean = {
vdef match {
case `mosquito` | `lightgunship` | `wasp` | `liberator` | `vulture` | `phantasm` | `lodestar` | `dropship` | `galaxy_gunship` =>
true
case _ =>
false
}
}
/**
* Initialize `AmmoBoxDefinition` globals.
*/
@ -2034,6 +2048,7 @@ object GlobalDefinitions {
* Initialize `VehicleDefinition` globals.
*/
private def init_vehicles() : Unit = {
fury.Name = "fury"
fury.Seats += 0 -> new SeatDefinition()
fury.Seats(0).Bailable = true
fury.Seats(0).ControlledWeapon = 1
@ -2042,7 +2057,9 @@ object GlobalDefinitions {
fury.MountPoints += 2 -> 0
fury.TrunkSize = InventoryTile.Tile1111
fury.TrunkOffset = 30
fury.AutoPilotSpeeds = (24, 10)
quadassault.Name = "quadassault"
quadassault.Seats += 0 -> new SeatDefinition()
quadassault.Seats(0).Bailable = true
quadassault.Seats(0).ControlledWeapon = 1
@ -2051,7 +2068,9 @@ object GlobalDefinitions {
quadassault.MountPoints += 2 -> 0
quadassault.TrunkSize = InventoryTile.Tile1111
quadassault.TrunkOffset = 30
quadassault.AutoPilotSpeeds = (24, 10)
quadstealth.Name = "quadstealth"
quadstealth.CanCloak = true
quadstealth.Seats += 0 -> new SeatDefinition()
quadstealth.Seats(0).Bailable = true
@ -2060,7 +2079,9 @@ object GlobalDefinitions {
quadstealth.MountPoints += 2 -> 0
quadstealth.TrunkSize = InventoryTile.Tile1111
quadstealth.TrunkOffset = 30
quadstealth.AutoPilotSpeeds = (24, 10)
two_man_assault_buggy.Name = "two_man_assault_buggy"
two_man_assault_buggy.Seats += 0 -> new SeatDefinition()
two_man_assault_buggy.Seats(0).Bailable = true
two_man_assault_buggy.Seats += 1 -> new SeatDefinition()
@ -2071,7 +2092,9 @@ object GlobalDefinitions {
two_man_assault_buggy.MountPoints += 2 -> 1
two_man_assault_buggy.TrunkSize = InventoryTile.Tile1511
two_man_assault_buggy.TrunkOffset = 30
two_man_assault_buggy.AutoPilotSpeeds = (22, 8)
skyguard.Name = "skyguard"
skyguard.Seats += 0 -> new SeatDefinition()
skyguard.Seats(0).Bailable = true
skyguard.Seats += 1 -> new SeatDefinition()
@ -2083,7 +2106,9 @@ object GlobalDefinitions {
skyguard.MountPoints += 3 -> 1
skyguard.TrunkSize = InventoryTile.Tile1511
skyguard.TrunkOffset = 30
skyguard.AutoPilotSpeeds = (22, 8)
threemanheavybuggy.Name = "threemanheavybuggy"
threemanheavybuggy.Seats += 0 -> new SeatDefinition()
threemanheavybuggy.Seats(0).Bailable = true
threemanheavybuggy.Seats += 1 -> new SeatDefinition()
@ -2099,7 +2124,9 @@ object GlobalDefinitions {
threemanheavybuggy.MountPoints += 3 -> 2
threemanheavybuggy.TrunkSize = InventoryTile.Tile1511
threemanheavybuggy.TrunkOffset = 30
threemanheavybuggy.AutoPilotSpeeds = (22, 8)
twomanheavybuggy.Name = "twomanheavybuggy"
twomanheavybuggy.Seats += 0 -> new SeatDefinition()
twomanheavybuggy.Seats(0).Bailable = true
twomanheavybuggy.Seats += 1 -> new SeatDefinition()
@ -2110,7 +2137,9 @@ object GlobalDefinitions {
twomanheavybuggy.MountPoints += 2 -> 1
twomanheavybuggy.TrunkSize = InventoryTile.Tile1511
twomanheavybuggy.TrunkOffset = 30
twomanheavybuggy.AutoPilotSpeeds = (22, 8)
twomanhoverbuggy.Name = "twomanhoverbuggy"
twomanhoverbuggy.Seats += 0 -> new SeatDefinition()
twomanhoverbuggy.Seats(0).Bailable = true
twomanhoverbuggy.Seats += 1 -> new SeatDefinition()
@ -2121,7 +2150,9 @@ object GlobalDefinitions {
twomanhoverbuggy.MountPoints += 2 -> 1
twomanhoverbuggy.TrunkSize = InventoryTile.Tile1511
twomanhoverbuggy.TrunkOffset = 30
twomanhoverbuggy.AutoPilotSpeeds = (22, 10)
mediumtransport.Name = "mediumtransport"
mediumtransport.Seats += 0 -> new SeatDefinition()
mediumtransport.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
mediumtransport.Seats += 1 -> new SeatDefinition()
@ -2139,7 +2170,9 @@ object GlobalDefinitions {
mediumtransport.MountPoints += 5 -> 4
mediumtransport.TrunkSize = InventoryTile.Tile1515
mediumtransport.TrunkOffset = 30
mediumtransport.AutoPilotSpeeds = (18, 6)
battlewagon.Name = "battlewagon"
battlewagon.Seats += 0 -> new SeatDefinition()
battlewagon.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
battlewagon.Seats += 1 -> new SeatDefinition()
@ -2161,7 +2194,9 @@ object GlobalDefinitions {
battlewagon.MountPoints += 5 -> 4
battlewagon.TrunkSize = InventoryTile.Tile1515
battlewagon.TrunkOffset = 30
battlewagon.AutoPilotSpeeds = (18, 6)
thunderer.Name = "thunderer"
thunderer.Seats += 0 -> new SeatDefinition()
thunderer.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
thunderer.Seats += 1 -> new SeatDefinition()
@ -2179,7 +2214,9 @@ object GlobalDefinitions {
thunderer.MountPoints += 5 -> 4
thunderer.TrunkSize = InventoryTile.Tile1515
thunderer.TrunkOffset = 30
thunderer.AutoPilotSpeeds = (18, 6)
aurora.Name = "aurora"
aurora.Seats += 0 -> new SeatDefinition()
aurora.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
aurora.Seats += 1 -> new SeatDefinition()
@ -2197,7 +2234,9 @@ object GlobalDefinitions {
aurora.MountPoints += 5 -> 4
aurora.TrunkSize = InventoryTile.Tile1515
aurora.TrunkOffset = 30
aurora.AutoPilotSpeeds = (18, 6)
apc_tr.Name = "apc_tr"
apc_tr.Seats += 0 -> new SeatDefinition()
apc_tr.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
apc_tr.Seats += 1 -> new SeatDefinition()
@ -2238,7 +2277,9 @@ object GlobalDefinitions {
apc_tr.MountPoints += 12 -> 10
apc_tr.TrunkSize = InventoryTile.Tile2016
apc_tr.TrunkOffset = 30
apc_tr.AutoPilotSpeeds = (16, 6)
apc_nc.Name = "apc_nc"
apc_nc.Seats += 0 -> new SeatDefinition()
apc_nc.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
apc_nc.Seats += 1 -> new SeatDefinition()
@ -2279,7 +2320,9 @@ object GlobalDefinitions {
apc_nc.MountPoints += 12 -> 10
apc_nc.TrunkSize = InventoryTile.Tile2016
apc_nc.TrunkOffset = 30
apc_nc.AutoPilotSpeeds = (16, 6)
apc_vs.Name = "apc_vs"
apc_vs.Seats += 0 -> new SeatDefinition()
apc_vs.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
apc_vs.Seats += 1 -> new SeatDefinition()
@ -2320,7 +2363,9 @@ object GlobalDefinitions {
apc_vs.MountPoints += 12 -> 10
apc_vs.TrunkSize = InventoryTile.Tile2016
apc_vs.TrunkOffset = 30
apc_vs.AutoPilotSpeeds = (16, 6)
lightning.Name = "lightning"
lightning.Seats += 0 -> new SeatDefinition()
lightning.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
lightning.Seats(0).ControlledWeapon = 1
@ -2329,7 +2374,9 @@ object GlobalDefinitions {
lightning.MountPoints += 2 -> 0
lightning.TrunkSize = InventoryTile.Tile1511
lightning.TrunkOffset = 30
lightning.AutoPilotSpeeds = (20, 8)
prowler.Name = "prowler"
prowler.Seats += 0 -> new SeatDefinition()
prowler.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
prowler.Seats += 1 -> new SeatDefinition()
@ -2343,7 +2390,9 @@ object GlobalDefinitions {
prowler.MountPoints += 3 -> 2
prowler.TrunkSize = InventoryTile.Tile1511
prowler.TrunkOffset = 30
prowler.AutoPilotSpeeds = (14, 6)
vanguard.Name = "vanguard"
vanguard.Seats += 0 -> new SeatDefinition()
vanguard.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
vanguard.Seats += 1 -> new SeatDefinition()
@ -2353,7 +2402,9 @@ object GlobalDefinitions {
vanguard.MountPoints += 2 -> 1
vanguard.TrunkSize = InventoryTile.Tile1511
vanguard.TrunkOffset = 30
vanguard.AutoPilotSpeeds = (16, 6)
magrider.Name = "magrider"
magrider.Seats += 0 -> new SeatDefinition()
magrider.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
magrider.Seats(0).ControlledWeapon = 2
@ -2365,14 +2416,18 @@ object GlobalDefinitions {
magrider.MountPoints += 2 -> 1
magrider.TrunkSize = InventoryTile.Tile1511
magrider.TrunkOffset = 30
magrider.AutoPilotSpeeds = (18, 6)
val utilityConverter = new UtilityVehicleConverter
ant.Name = "ant"
ant.Seats += 0 -> new SeatDefinition()
ant.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
ant.MountPoints += 1 -> 0
ant.MountPoints += 2 -> 0
ant.AutoPilotSpeeds = (18, 6)
ant.Packet = utilityConverter
ams.Name = "ams"
ams.Seats += 0 -> new SeatDefinition()
ams.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
ams.MountPoints += 1 -> 0
@ -2384,9 +2439,11 @@ object GlobalDefinitions {
ams.Deployment = true
ams.DeployTime = 2000
ams.UndeployTime = 2000
ams.AutoPilotSpeeds = (18, 6)
ams.Packet = utilityConverter
val variantConverter = new VariantVehicleConverter
router.Name = "router"
router.Seats += 0 -> new SeatDefinition()
router.MountPoints += 1 -> 0
router.TrunkSize = InventoryTile.Tile1511
@ -2394,8 +2451,10 @@ object GlobalDefinitions {
router.Deployment = true
router.DeployTime = 2000
router.UndeployTime = 2000
router.AutoPilotSpeeds = (16, 6)
router.Packet = variantConverter
switchblade.Name = "switchblade"
switchblade.Seats += 0 -> new SeatDefinition()
switchblade.Seats(0).ControlledWeapon = 1
switchblade.Weapons += 1 -> scythe
@ -2406,8 +2465,10 @@ object GlobalDefinitions {
switchblade.Deployment = true
switchblade.DeployTime = 2000
switchblade.UndeployTime = 2000
switchblade.AutoPilotSpeeds = (22, 8)
switchblade.Packet = variantConverter
flail.Name = "flail"
flail.Seats += 0 -> new SeatDefinition()
flail.Seats(0).ControlledWeapon = 1
flail.Weapons += 1 -> flail_weapon
@ -2417,8 +2478,10 @@ object GlobalDefinitions {
flail.Deployment = true
flail.DeployTime = 2000
flail.UndeployTime = 2000
flail.AutoPilotSpeeds = (14, 6)
flail.Packet = variantConverter
mosquito.Name = "mosquito"
mosquito.Seats += 0 -> new SeatDefinition()
mosquito.Seats(0).Bailable = true
mosquito.Seats(0).ControlledWeapon = 1
@ -2427,8 +2490,10 @@ object GlobalDefinitions {
mosquito.MountPoints += 2 -> 0
mosquito.TrunkSize = InventoryTile.Tile1111
mosquito.TrunkOffset = 30
mosquito.AutoPilotSpeeds = (0, 6)
mosquito.Packet = variantConverter
lightgunship.Name = "lightgunship"
lightgunship.Seats += 0 -> new SeatDefinition()
lightgunship.Seats(0).Bailable = true
lightgunship.Seats(0).ControlledWeapon = 1
@ -2437,8 +2502,10 @@ object GlobalDefinitions {
lightgunship.MountPoints += 2 -> 0
lightgunship.TrunkSize = InventoryTile.Tile1511
lightgunship.TrunkOffset = 30
lightgunship.AutoPilotSpeeds = (0, 4)
lightgunship.Packet = variantConverter
wasp.Name = "wasp"
wasp.Seats += 0 -> new SeatDefinition()
wasp.Seats(0).Bailable = true
wasp.Seats(0).ControlledWeapon = 1
@ -2447,8 +2514,10 @@ object GlobalDefinitions {
wasp.MountPoints += 2 -> 0
wasp.TrunkSize = InventoryTile.Tile1111
wasp.TrunkOffset = 30
wasp.AutoPilotSpeeds = (0, 6)
wasp.Packet = variantConverter
liberator.Name = "liberator"
liberator.Seats += 0 -> new SeatDefinition()
liberator.Seats(0).ControlledWeapon = 3
liberator.Seats += 1 -> new SeatDefinition()
@ -2464,8 +2533,10 @@ object GlobalDefinitions {
liberator.MountPoints += 4 -> 2
liberator.TrunkSize = InventoryTile.Tile1515
liberator.TrunkOffset = 30
liberator.AutoPilotSpeeds = (0, 4)
liberator.Packet = variantConverter
vulture.Name = "vulture"
vulture.Seats += 0 -> new SeatDefinition()
vulture.Seats(0).ControlledWeapon = 3
vulture.Seats += 1 -> new SeatDefinition()
@ -2481,8 +2552,10 @@ object GlobalDefinitions {
vulture.MountPoints += 4 -> 2
vulture.TrunkSize = InventoryTile.Tile1611
vulture.TrunkOffset = 30
vulture.AutoPilotSpeeds = (0, 4)
vulture.Packet = variantConverter
dropship.Name = "dropship"
dropship.Seats += 0 -> new SeatDefinition()
dropship.Seats += 1 -> new SeatDefinition()
dropship.Seats(1).Bailable = true
@ -2528,8 +2601,10 @@ object GlobalDefinitions {
dropship.MountPoints += 12 -> 10
dropship.TrunkSize = InventoryTile.Tile1612
dropship.TrunkOffset = 30
dropship.AutoPilotSpeeds = (0, 4)
dropship.Packet = variantConverter
galaxy_gunship.Name = "galaxy_gunship"
galaxy_gunship.Seats += 0 -> new SeatDefinition()
galaxy_gunship.Seats += 1 -> new SeatDefinition()
galaxy_gunship.Seats(1).ControlledWeapon = 6
@ -2554,14 +2629,18 @@ object GlobalDefinitions {
galaxy_gunship.MountPoints += 6 -> 5
galaxy_gunship.TrunkSize = InventoryTile.Tile1816
galaxy_gunship.TrunkOffset = 30
galaxy_gunship.AutoPilotSpeeds = (0, 4)
galaxy_gunship.Packet = variantConverter
lodestar.Name = "lodestar"
lodestar.Seats += 0 -> new SeatDefinition()
lodestar.MountPoints += 1 -> 0
lodestar.TrunkSize = InventoryTile.Tile1612
lodestar.TrunkOffset = 30
lodestar.AutoPilotSpeeds = (0, 4)
lodestar.Packet = variantConverter
phantasm.Name = "phantasm"
phantasm.CanCloak = true
phantasm.Seats += 0 -> new SeatDefinition()
phantasm.Seats += 1 -> new SeatDefinition()
@ -2579,6 +2658,7 @@ object GlobalDefinitions {
phantasm.MountPoints += 5 -> 4
phantasm.TrunkSize = InventoryTile.Tile1107
phantasm.TrunkOffset = 30
phantasm.AutoPilotSpeeds = (0, 6)
phantasm.Packet = variantConverter
}
}

View file

@ -28,6 +28,7 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
private var trunkOffset : Int = 0
private var canCloak : Boolean = false
private var canBeOwned : Boolean = true
private var serverVehicleOverrideSpeeds : (Int, Int) = (0, 0)
Name = "vehicle"
Packet = VehicleDefinition.converter
@ -102,6 +103,17 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
trunkOffset = offset
TrunkOffset
}
def AutoPilotSpeeds : (Int, Int) = serverVehicleOverrideSpeeds
def AutoPilotSpeeds_=(speeds : (Int, Int)) : (Int, Int) = {
serverVehicleOverrideSpeeds = speeds
AutoPilotSpeeds
}
def AutoPilotSpeed1 : Int = serverVehicleOverrideSpeeds._1
def AutoPilotSpeed2 : Int = serverVehicleOverrideSpeeds._2
}
object VehicleDefinition {

View file

@ -156,7 +156,6 @@ object VehicleSpawnControl {
final case class AwaitDriverInSeat(entry : VehicleSpawnControl.Order) extends Order(entry)
final case class DriverInSeat(entry : VehicleSpawnControl.Order) extends Order(entry)
final case class RailJackAction(entry : VehicleSpawnControl.Order) extends Order(entry)
final case class RailJackRelease(entry : VehicleSpawnControl.Order) extends Order(entry)
final case class ServerVehicleOverride(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)
@ -172,12 +171,12 @@ object VehicleSpawnControl {
/**
* Properly clean up a vehicle that has been registered, but not yet been spawned into the game world.
* @param vehicle the vehicle
* @param player the driver
* @see `VehicleSpawnControl.emergencyResolver`
* @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(vehicle : Vehicle, player : Player, zone: Zone)(implicit context : ActorContext) : Unit = {
def DisposeVehicle(entry : VehicleSpawnControl.Order, zone: Zone)(implicit context : ActorContext) : Unit = {
import net.psforever.objects.guid.GUIDTask
emergencyResolver.getOrElse({
import akka.routing.SmallestMailboxPool
@ -185,18 +184,18 @@ object VehicleSpawnControl {
val resolver = context.actorOf(SmallestMailboxPool(10).props(Props[TaskResolver]), "vehicle-spawn-control-emergency-decon-resolver")
emergencyResolver = Some(resolver)
resolver
}) ! GUIDTask.UnregisterVehicle(vehicle)(zone.GUID)
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(player.GUID, zone.Id)
}) ! GUIDTask.UnregisterVehicle(entry.vehicle)(zone.GUID)
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(entry.driver.GUID, zone.Id)
}
/**
* Properly clean up a vehicle that has been registered and spawned into the game world.
* @param vehicle the vehicle
* @param player the driver
* @param entry the order being cancelled
* @param zone the continent on which the vehicle was registered
*/
def DisposeSpawnedVehicle(vehicle : Vehicle, player : Player, zone: Zone) : Unit = {
zone.VehicleEvents ! VehicleSpawnPad.DisposeVehicle(vehicle, zone)
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(player.GUID, zone.Id)
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)
}
/**

View file

@ -13,10 +13,28 @@ import net.psforever.packet.game.PlanetSideGUID
* 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`.
* @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
* @see `VehicleSpawnControl`
* @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
class VehicleSpawnPad(spDef : VehicleSpawnPadDefinition) extends Amenity {
/**
* USE THIS BOOLEAN FOR DEVELOPMENT PURPOSES!<br>
* Purpose: use the ingame railed platform to lift the spawned vehicle out of the trench.
* When set, the client performs the standard vehicle entry procedure, including rail 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.
* The main reason to disable this feature is to avoid an `ObjectAttachMessage` that may be dispatched for an incorrect object.
* Unset if not guaranteed to have the correct ingame globally unique id of the spawn pad.
*/
private var onRails : Boolean = true
def Railed : Boolean = onRails
def Railed_=(useRails : Boolean) : Boolean = {
onRails = useRails
Railed
}
def Definition : VehicleSpawnPadDefinition = spDef
}
@ -53,7 +71,11 @@ object VehicleSpawnPad {
*/
final case class LoadVehicle(vehicle : Vehicle, zone : Zone)
final case class StartPlayerSeatedInVehicle(vehicle : Vehicle)
final case class AttachToRails(vehicle : Vehicle, pad : VehicleSpawnPad, zone_id : String)
final case class DetachFromRails(vehicle : Vehicle, pad : VehicleSpawnPad, zone_id : String)
final case class StartPlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad)
/**
* A TEMPORARY callback step in spawning the vehicle.
@ -62,11 +84,13 @@ object VehicleSpawnPad {
* This message is the next step after that.
* @param vehicle the vehicle being spawned
*/
final case class PlayerSeatedInVehicle(vehicle : Vehicle)
final case class PlayerSeatedInVehicle(vehicle : Vehicle, pad : VehicleSpawnPad) //TODO while using fake rails
final case class ServerVehicleOverrideStart(speed : Int)
final case class ServerVehicleOverrideStart(vehicle : Vehicle, pad : VehicleSpawnPad)
final case class ServerVehicleOverrideEnd(speed : Int)
final case class ServerVehicleOverrideEnd(vehicle : Vehicle, pad : VehicleSpawnPad)
final case class ResetSpawnPad(pad : VehicleSpawnPad, zone_id : String)
final case class PeriodicReminder(msg : String)

View file

@ -55,7 +55,7 @@ abstract class VehicleSpawnControlBase(pad : VehicleSpawnPad) extends Actor {
* No important messages should processed by this agent; only consume general vehicle spawn status.
* @param msg the message
*/
def trace(msg : String) : Unit = log.info(msg)
def trace(msg : String) : Unit = log.trace(msg)
protected def Pad : VehicleSpawnPad = pad

View file

@ -34,7 +34,7 @@ class VehicleSpawnControlConcealPlayer(pad : VehicleSpawnPad) extends VehicleSpa
}
else {
trace(s"integral component lost; abort order fulfillment")
VehicleSpawnControl.DisposeVehicle(entry.vehicle, driver, Continent)
VehicleSpawnControl.DisposeVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
}

View file

@ -2,7 +2,9 @@
package net.psforever.objects.serverobject.pad.process
import akka.actor.Props
import net.psforever.objects.GlobalDefinitions
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
import net.psforever.types.Vector3
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
@ -28,12 +30,13 @@ class VehicleSpawnControlLoadVehicle(pad : VehicleSpawnPad) extends VehicleSpawn
val vehicle = entry.vehicle
if(entry.driver.Continent == Continent.Id) {
trace(s"loading the ${vehicle.Definition.Name}")
vehicle.Position = vehicle.Position - Vector3(0, 0, if(GlobalDefinitions.isFlightVehicle(vehicle.Definition)) 9 else 5)
Continent.VehicleEvents ! VehicleSpawnPad.LoadVehicle(vehicle, Continent)
context.system.scheduler.scheduleOnce(100 milliseconds, seatDriver, VehicleSpawnControl.Process.SeatDriver(entry))
}
else {
trace("owner lost; abort order fulfillment")
VehicleSpawnControl.DisposeVehicle(vehicle, entry.driver, Continent)
VehicleSpawnControl.DisposeVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetOrder
}

View file

@ -14,12 +14,13 @@ import scala.concurrent.duration._
* <br>
* When the vehicle is added into the environment, it is attached to the spawn pad platform.
* On cue, the trapdoor of the platform will open, and the vehicle will be raised up into plain sight on a group of rails.
* It has failure cases should the driver be in an incorrect state.<br>
* __It currently does not work__.
* These actions are actually integrated into previous stages and into later stages of the process.
* The primary objective to be completed is a specific place to start a frequent message to the other customers.
* It has failure cases should the driver be in an incorrect state.
* @param pad the `VehicleSpawnPad` object being governed
*/
class VehicleSpawnControlRailJack(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) {
def LogId = "-jacker"
def LogId = "-lifter"
val vehicleOverride = context.actorOf(Props(classOf[VehicleSpawnControlServerVehicleOverride], pad), s"${context.parent.path.name}-override")
@ -27,8 +28,8 @@ class VehicleSpawnControlRailJack(pad : VehicleSpawnPad) extends VehicleSpawnCon
case VehicleSpawnControl.Process.RailJackAction(entry) =>
if(entry.vehicle.Health == 0) {
//TODO detach vehicle from pad rails if necessary
trace(s"vehicle was already destroyed; clean it up")
VehicleSpawnControl.DisposeSpawnedVehicle(entry.vehicle, entry.driver, Continent)
trace(s"vehicle was already destroyed")
VehicleSpawnControl.DisposeSpawnedVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
}
else {

View file

@ -35,29 +35,32 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
else {
val driver = entry.driver
if(entry.vehicle.Health == 0) {
//TODO detach vehicle from pad rails if necessary
trace("vehicle was already destroyed; clean it up")
VehicleSpawnControl.DisposeSpawnedVehicle(entry.vehicle, driver, Continent)
VehicleSpawnControl.DisposeSpawnedVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
}
else if(entry.sendTo != ActorRef.noSender && driver.isAlive && driver.Continent == Continent.Id && driver.VehicleSeated.isEmpty) {
trace("driver to be made seated in vehicle")
entry.sendTo ! VehicleSpawnPad.StartPlayerSeatedInVehicle(entry.vehicle)
entry.vehicle.Actor.tell(Mountable.TryMount(driver, 0), entry.sendTo) //entry.sendTo should handle replies to TryMount
context.system.scheduler.scheduleOnce(1000 milliseconds, self, VehicleSpawnControl.Process.AwaitDriverInSeat(entry))
}
else {
trace("driver lost; vehicle stranded on pad")
context.system.scheduler.scheduleOnce(1000 milliseconds, railJack, VehicleSpawnControl.Process.RailJackAction(entry))
if(entry.sendTo != ActorRef.noSender && driver.isAlive && driver.Continent == Continent.Id && 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(1000 milliseconds, self, VehicleSpawnControl.Process.AwaitDriverInSeat(entry))
}
else {
if(pad.Railed) {
Continent.VehicleEvents ! VehicleSpawnPad.AttachToRails(entry.vehicle, pad, Continent.Id)
}
trace("driver lost; vehicle stranded on pad")
context.system.scheduler.scheduleOnce(1000 milliseconds, railJack, VehicleSpawnControl.Process.RailJackAction(entry))
}
}
}
case VehicleSpawnControl.Process.AwaitDriverInSeat(entry) =>
val driver = entry.driver
if(entry.vehicle.Health == 0) {
//TODO detach vehicle from pad rails if necessary
trace("vehicle was already destroyed; clean it up")
VehicleSpawnControl.DisposeSpawnedVehicle(entry.vehicle, driver, Continent)
VehicleSpawnControl.DisposeSpawnedVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
}
else if(entry.sendTo == ActorRef.noSender) {
@ -65,23 +68,27 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
self ! VehicleSpawnControl.Process.RailJackAction(entry)
}
else if(driver.isAlive && driver.Continent == Continent.Id && driver.VehicleSeated.isEmpty) {
context.system.scheduler.scheduleOnce(1000 milliseconds, self, VehicleSpawnControl.Process.AwaitDriverInSeat(entry))
context.system.scheduler.scheduleOnce(100 milliseconds, self, VehicleSpawnControl.Process.AwaitDriverInSeat(entry))
}
else {
trace(s"driver is sitting down")
context.system.scheduler.scheduleOnce(1000 milliseconds, self, VehicleSpawnControl.Process.DriverInSeat(entry))
context.system.scheduler.scheduleOnce(
VehicleSpawnControlSeatDriver.RaillessSeatAnimationTimes(entry.vehicle.Definition.Name) milliseconds,
self,
VehicleSpawnControl.Process.DriverInSeat(entry)
)
}
case VehicleSpawnControl.Process.DriverInSeat(entry) =>
if(entry.vehicle.Health == 0) {
//TODO detach vehicle from pad rails if necessary
trace(s"vehicle was already destroyed; clean it up")
VehicleSpawnControl.DisposeSpawnedVehicle(entry.vehicle, entry.driver, Continent)
VehicleSpawnControl.DisposeSpawnedVehicle(entry, Continent)
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
}
else if(entry.sendTo != ActorRef.noSender) {
trace(s"driver ${entry.driver.Name} has taken the wheel")
entry.sendTo ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle)
entry.sendTo ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad)
context.system.scheduler.scheduleOnce(10 milliseconds, railJack, VehicleSpawnControl.Process.RailJackAction(entry))
}
else {
@ -98,3 +105,44 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
case _ => ;
}
}
object VehicleSpawnControlSeatDriver {
/**
* 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,
"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)
}

View file

@ -33,31 +33,35 @@ class VehicleSpawnControlServerVehicleOverride(pad : VehicleSpawnPad) extends Ve
}
else if(entry.sendTo != ActorRef.noSender && entry.driver.VehicleSeated.contains(vehicle.GUID)) {
trace(s"telling ${entry.driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}")
entry.sendTo ! VehicleSpawnPad.ServerVehicleOverrideStart(22)
entry.sendTo ! VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad)
context.system.scheduler.scheduleOnce(3000 milliseconds, self, VehicleSpawnControl.Process.DriverVehicleControl(entry))
}
else {
if(pad.Railed) {
Continent.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad, Continent.Id)
}
finalClear ! VehicleSpawnControl.Process.FinalClearance(entry)
}
case VehicleSpawnControl.Process.DriverVehicleControl(entry) =>
val vehicle = entry.vehicle
if(vehicle.Health == 0) {
trace(s"vehicle was already destroyed; but, everything is fine")
}
if(entry.sendTo != ActorRef.noSender) {
if(vehicle.Health == 0) {
trace(s"vehicle was already destroyed; but, everything is fine")
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 {
val driver = entry.driver
entry.sendTo ! VehicleSpawnPad.ServerVehicleOverrideEnd(8)
if(driver.VehicleSeated.contains(vehicle.GUID)) {
trace(s"returning control of ${vehicle.Definition.Name} to ${driver.Name}")
}
else {
trace(s"${driver.Name} is no longer seated in new ${vehicle.Definition.Name}; can not properly return control to driver")
}
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; can not properly return control to driver")
}
}
else {
if(pad.Railed) {
Continent.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad, Continent.Id)
}
trace("can not properly return control to driver")
}
finalClear ! VehicleSpawnControl.Process.FinalClearance(entry)

View file

@ -10,9 +10,13 @@ import scodec.codecs._
* <br>
* The "vehicle" counts as any mobile platform where the user's character is currently sitting.
* If the player is not sitting in what the game considers a "vehicle," the packet is wasted.
* Either of the first two parameters - `lock_accelerator` or `lock_wheel` - constitutes the vehicle being overrode.
* No message is displayed if the vehicle is placed under server control.
* The vehicle will operate as if accelerating.<br>
* Either of the first two parameters - `lock_accelerator` or `lock_wheel` - constitutes any vehicle being overrode.
* Either of the latter two parameters - `lock_thrust` or `lock_strafe` - constitutes a flight vehicle being overrode.
* No message is displayed if the vehicle is placed under any form of server control.
* During server control, this is an acceleration value (?);
* during cancellable auto-drive, a constant velocity value.
* Vertical thrust control for aircraft is either on or off;
* the amount of that thrust can not be controlled.<br>
* <br>
* After being controlled, when the vehicle is no longer under control,
* it will transition into a state of constant speed auto-drive.
@ -22,33 +26,30 @@ import scodec.codecs._
* the player will behave like they are bailing from it.
* (The vehicle actually has to be "bailable" first, of course.)<br>
* <br>
* Speed samples follow (from AMS):<br>
* 1 -> 3<br>
* 2 -> 7<br>
* 3 -> 10<br>
* 10 -> 35<br>
* 15 -> 52<br>
* 20 -> 68
* @param lock_accelerator driver has no control over whether vehicle accelerates
* @param lock_wheel driver has no control over whether the vehicle turns
* @param reverse drive in reverse
* "Something like speed:"<br>
* For ground vehicles, for `n`, the calculated in-game speed for the value in this packet will be at least `3.45 x n`.
* For flight vehicles, for `n`, the forward air speed for the value in this packet will be at least `1.18 * n`.
* This approximation is not always going to be accurate but serves as a good rule of thumb.
* @param lock_accelerator driver has no control over vehicle acceleration
* @param lock_wheel driver has no control over vehicle turning
* @param reverse move in reverse
* @param unk4 na
* @param unk5 na
* @param unk6 na
* @param speed "something like speed;"
* for `n`, the pattern to calculate a constant in-game speed is `floor(3.5 x n)`;
* during server control, an acceleration value (?);
* during auto-drive, a velocity value
* @param lock_vthrust pilot has no control over vertical thrust;
* asserts a constant positive vertical thrust;
* the only valid setting appears to be 1
* @param lock_strafe pilot has no control over strafing thrust;
* the only valid setting appears to be 1
* @param forward_speed "something like speed"
* @param unk8 na;
* set `lock_wheel` to `true` to expose value
* set `lock_wheel` to `true` to expose this value
*/
final case class ServerVehicleOverrideMsg(lock_accelerator : Boolean,
lock_wheel : Boolean,
reverse : Boolean,
unk4 : Boolean,
unk5 : Int,
unk6 : Int,
speed : Int,
lock_vthrust : Int,
lock_strafe : Int,
forward_speed : Int,
unk8 : Option[Long]
) extends PlanetSideGamePacket {
type Packet = ServerVehicleOverrideMsg
@ -58,20 +59,22 @@ final case class ServerVehicleOverrideMsg(lock_accelerator : Boolean,
object ServerVehicleOverrideMsg extends Marshallable[ServerVehicleOverrideMsg] {
/**
* Common assert control packet format.
* Common lock control packet format.
* Strafing is always treated as unlocked.
* @param flight vehicle flies and should move vertically
* @param speed "something like speed"
* @return a `ServerVehicleOverrideMsg` packet
*/
def On(speed : Int) : ServerVehicleOverrideMsg = {
ServerVehicleOverrideMsg(true, true, false, false, 0, 0, speed, Some(0))
def Lock(flight : Int, speed : Int) : ServerVehicleOverrideMsg = {
ServerVehicleOverrideMsg(true, true, false, false, flight, 0, speed, Some(0))
}
/**
* Common relinquish control packet format.
* Common cancellable auto-drive packet format.
* @param speed "something like speed"
* @return a `ServerVehicleOverrideMsg` packet
*/
def Off(speed : Int) : ServerVehicleOverrideMsg = {
def Auto(speed : Int) : ServerVehicleOverrideMsg = {
ServerVehicleOverrideMsg(false, false, false, true, 0, 0, speed, None)
}
@ -80,9 +83,9 @@ object ServerVehicleOverrideMsg extends Marshallable[ServerVehicleOverrideMsg] {
(("lock_wheel" | bool) >>:~ { test =>
("reverse" | bool) ::
("unk4" | bool) ::
("unk5" | uint2L) ::
("unk6" | uint2L) ::
("speed" | uintL(9)) ::
("lock_vthrust" | uint2L) ::
("lock_strafe" | uint2L) ::
("forward_speed" | uintL(9)) ::
conditional(test, "unk8" | uint32L)
})
).as[ServerVehicleOverrideMsg]

View file

@ -58,14 +58,14 @@ class ServerVehicleOverrideMsgTest extends Specification {
}
"encode (3)" in {
val msg = ServerVehicleOverrideMsg.On(12)
val msg = ServerVehicleOverrideMsg.Lock(0, 12)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string1
}
"encode (4)" in {
val msg = ServerVehicleOverrideMsg.Off(5)
val msg = ServerVehicleOverrideMsg.Auto(5)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string2

View file

@ -74,6 +74,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
var progressBarUpdate : Cancellable = DefaultCancellable.obj
var reviveTimer : Cancellable = DefaultCancellable.obj
/**
* Convert a boolean value into an integer value.
* Use: `true:Int` or `false:Int`
* @param b `true` or `false` (or `null`)
* @return 1 for `true`; 0 for `false`
*/
implicit def boolToInt(b : Boolean) : Int = if(b) 1 else 0
override def postStop() = {
clientKeepAlive.cancel
reviveTimer.cancel
@ -404,6 +412,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
//resets exclamation point fte marker (once)
sendResponse(PlanetsideAttributeMessage(guid, 21, vehicle_guid.guid.toLong))
case VehicleResponse.AttachToRails(vehicle_guid, pad_guid) =>
sendResponse(ObjectAttachMessage(pad_guid, vehicle_guid, 3))
case VehicleResponse.ChildObjectState(object_guid, pitch, yaw) =>
if(tplayer_guid != guid) {
sendResponse(ChildObjectStateMessage(object_guid, pitch, yaw))
@ -422,6 +433,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(DeployRequestMessage(guid, object_guid, state, unk1, unk2, pos))
}
case VehicleResponse.DetachFromRails(vehicle_guid, pad_guid, pad_position, pad_orientation_z) =>
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0,0,0.5f), 0, 0, pad_orientation_z))
case VehicleResponse.InventoryState(obj, parent_guid, start, con_data) =>
if(tplayer_guid != guid) {
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
@ -459,6 +473,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ObjectAttachMessage(vehicle_guid, guid, seat))
}
case VehicleResponse.ResetSpawnPad(pad_guid) =>
sendResponse(GenericObjectActionMessage(pad_guid, 92))
case VehicleResponse.RevealPlayer(player_guid) =>
//TODO any action will cause the player to appear after the effects of ConcealPlayer
@ -1006,12 +1023,15 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, msg.transaction_type, false))
}
case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle) =>
case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, pad) =>
val vehicle_guid = vehicle.GUID
if(pad.Railed) {
sendResponse(ObjectAttachMessage(pad.GUID, vehicle_guid, 3))
}
sendResponse(PlanetsideAttributeMessage(vehicle_guid, 22, 1L)) //mount points off?
sendResponse(PlanetsideAttributeMessage(vehicle_guid, 21, player.GUID.guid)) //fte and ownership?
case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle) =>
case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle, pad) =>
val vehicle_guid = vehicle.GUID
if(player.VehicleSeated.nonEmpty) {
vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(vehicle_guid)
@ -1022,11 +1042,16 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(PlanetsideAttributeMessage(vehicle_guid, 113, 0L)) //???
ReloadVehicleAccessPermissions(vehicle)
case VehicleSpawnPad.ServerVehicleOverrideStart(speed) =>
sendResponse(ServerVehicleOverrideMsg.On(speed))
case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad) =>
val vdef = vehicle.Definition
if(vehicle.Seats(0).isOccupied) {
sendResponse(ObjectDetachMessage(pad.GUID, vehicle.GUID, pad.Position + Vector3(0, 0, 0.5f), 0, 0, pad.Orientation.z))
}
sendResponse(ServerVehicleOverrideMsg.Lock(GlobalDefinitions.isFlightVehicle(vdef):Int, vdef.AutoPilotSpeed1))
case VehicleSpawnPad.ServerVehicleOverrideEnd(speed) =>
sendResponse(ServerVehicleOverrideMsg.Off(speed))
case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad) =>
sendResponse(GenericObjectActionMessage(pad.GUID, 92)) //reset spawn pad
sendResponse(ServerVehicleOverrideMsg.Auto(vehicle.Definition.AutoPilotSpeed2))
case VehicleSpawnPad.PeriodicReminder(msg) =>
sendResponse(ChatMsg(ChatMessageType.CMT_OPEN, true, "", msg, None))

View file

@ -1,5 +1,6 @@
// Copyright (c) 2017 PSForever
import akka.actor.ActorContext
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
import net.psforever.objects.zones.Zone
import net.psforever.types.PlanetSideEmpire
@ -49,6 +50,9 @@ object Zones {
import net.psforever.types.PlanetSideEmpire
Buildings.values.foreach { _.Faction = PlanetSideEmpire.VS }
Building(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower
GUID(293).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 52
GUID(710).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 79
GUID(712).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 81
}
}

View file

@ -9,15 +9,18 @@ import net.psforever.types.{DriveState, Vector3}
object VehicleResponse {
trait Response
final case class AttachToRails(vehicle_guid : PlanetSideGUID, rails_guid : PlanetSideGUID) extends Response
final case class Awareness(vehicle_guid : PlanetSideGUID) extends Response
final case class ChildObjectState(object_guid : PlanetSideGUID, pitch : Float, yaw : Float) extends Response
final case class 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(unk1 : Int, unk2 : Boolean) extends Response
final case class InventoryState(obj : PlanetSideGameObject, parent_guid : PlanetSideGUID, start : Int, con_data : ConstructorData) extends Response
final case class KickPassenger(unk1 : Int, unk2 : Boolean, vehicle_guid : PlanetSideGUID) extends Response
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 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

View file

@ -116,6 +116,24 @@ class VehicleService extends Actor {
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ConcealPlayer(player_guid))
)
//from VehicleSpawnControl
case VehicleSpawnPad.AttachToRails(vehicle, pad, zone_id) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.AttachToRails(vehicle.GUID, pad.GUID))
)
//from VehicleSpawnControl
case VehicleSpawnPad.DetachFromRails(vehicle, pad, zone_id) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.DetachFromRails(vehicle.GUID, pad.GUID, pad.Position, pad.Orientation.z))
)
//from VehicleSpawnControl
case VehicleSpawnPad.ResetSpawnPad(pad, zone_id) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.ResetSpawnPad(pad.GUID))
)
case VehicleSpawnPad.RevealPlayer(player_guid, zone_id) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$zone_id/Vehicle", Service.defaultPlayerGUID, VehicleResponse.RevealPlayer(player_guid))