mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-02-27 18:43:39 +00:00
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:
parent
fde49773cd
commit
c87273c351
16 changed files with 314 additions and 90 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue