applying corrected properties to object definitions and applying them to interference tests for deployable ce and for deploying vehicles; made two otherwise useles object definitions to store property data (if we ever need ziplines or teleport pads ...)

This commit is contained in:
Fate-JH 2024-04-01 19:06:00 -04:00
parent 6813778019
commit e97900cfb4
10 changed files with 187 additions and 95 deletions

View file

@ -1080,4 +1080,22 @@ object WorldSession {
task
)
}
def CallBackForTask(task: TaskBundle, sendTo: ActorRef, pass: Any, replyTo: ActorRef): TaskBundle = {
TaskBundle(
new StraightforwardTask() {
private val localDesc = task.description()
private val destination = sendTo
private val passMsg = pass
override def description(): String = s"callback for tasking $localDesc"
def action() : Future[Any] = {
destination.tell(passMsg, replyTo)
Future(this)
}
},
task
)
}
}

View file

@ -27,6 +27,7 @@ import net.psforever.objects.vital._
import net.psforever.types.{ExoSuitType, ImplantType, PlanetSideEmpire, Vector3}
import net.psforever.types._
import net.psforever.objects.serverobject.llu.{CaptureFlagDefinition, CaptureFlagSocketDefinition}
import net.psforever.objects.serverobject.zipline.GenericTeleportationDefinition
import scala.annotation.switch
@ -1277,6 +1278,10 @@ object GlobalDefinitions {
val targeting_laser_dispenser = new OrderTerminalDefinition(851)
val stationaryteleportpad = new GenericTeleportationDefinition(836)
val zipline = new GenericTeleportationDefinition(1047)
/*
Buildings
*/
@ -1294,29 +1299,28 @@ object GlobalDefinitions {
val vanu_core = new BuildingDefinition(932)
//the following group borrows the object id from entity mainbase1
val ground_bldg_a = new BuildingDefinition(474)
val ground_bldg_b = new BuildingDefinition(474)
val ground_bldg_c = new BuildingDefinition(474)
val ground_bldg_d = new BuildingDefinition(474)
val ground_bldg_e = new BuildingDefinition(474)
val ground_bldg_f = new BuildingDefinition(474)
val ground_bldg_g = new BuildingDefinition(474)
val ground_bldg_h = new BuildingDefinition(474)
val ground_bldg_i = new BuildingDefinition(474)
val ground_bldg_j = new BuildingDefinition(474)
val ground_bldg_z = new BuildingDefinition(474)
val ceiling_bldg_a = new BuildingDefinition(474)
val ceiling_bldg_b = new BuildingDefinition(474)
val ceiling_bldg_c = new BuildingDefinition(474)
val ceiling_bldg_d = new BuildingDefinition(474)
val ceiling_bldg_e = new BuildingDefinition(474)
val ceiling_bldg_f = new BuildingDefinition(474)
val ceiling_bldg_g = new BuildingDefinition(474)
val ceiling_bldg_h = new BuildingDefinition(474)
val ceiling_bldg_i = new BuildingDefinition(474)
val ceiling_bldg_j = new BuildingDefinition(474)
val ceiling_bldg_z = new BuildingDefinition(474)
val ground_bldg_a = new BuildingDefinition(373)
val ground_bldg_b = new BuildingDefinition(374)
val ground_bldg_c = new BuildingDefinition(375)
val ground_bldg_d = new BuildingDefinition(376)
val ground_bldg_e = new BuildingDefinition(377)
val ground_bldg_f = new BuildingDefinition(378)
val ground_bldg_g = new BuildingDefinition(379)
val ground_bldg_h = new BuildingDefinition(380)
val ground_bldg_i = new BuildingDefinition(381)
val ground_bldg_j = new BuildingDefinition(382)
val ground_bldg_z = new BuildingDefinition(383)
val ceiling_bldg_a = new BuildingDefinition(159)
val ceiling_bldg_b = new BuildingDefinition(160)
val ceiling_bldg_c = new BuildingDefinition(161)
val ceiling_bldg_d = new BuildingDefinition(162)
val ceiling_bldg_e = new BuildingDefinition(163)
val ceiling_bldg_f = new BuildingDefinition(164)
val ceiling_bldg_g = new BuildingDefinition(165)
val ceiling_bldg_h = new BuildingDefinition(166)
val ceiling_bldg_i = new BuildingDefinition(167)
val ceiling_bldg_j = new BuildingDefinition(168)
val ceiling_bldg_z = new BuildingDefinition(169)
val mainbase1 = new BuildingDefinition(474)

View file

@ -5,61 +5,9 @@ import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.definition.converter.{ObjectCreateConverter, PacketConverter}
import net.psforever.objects.geometry.GeometryForm
import net.psforever.objects.geometry.d3.VolumetricGeometry
import net.psforever.objects.serverobject.deploy.{Interference, InterferenceRange}
import net.psforever.types.OxygenState
/*
Line 1316: add_property ams interference_range 125
Line 1392: add_property ams shared_interference_range 30
Line 5977: add_property boomer interference_range 0.2
Line 8735: add_property deployable_shield_generator deployable_interference_range 2.0
Line 8775: add_property deployable_shield_generator interference_range 125
Line 8798: add_property deployable_shield_generator shared_interference_range 60
Line 13684: add_property he_mine deployable_interference_range 0.1
Line 13695: add_property he_mine interference_range 7
Line 13709: add_property he_mine shared_interference_range 7
Line 14634: add_property jammer_mine deployable_interference_range 0.1
Line 14645: add_property jammer_mine interference_range 7
Line 14661: add_property jammer_mine shared_interference_range 7
Line 21038: add_property motion_alarm_sensor_dest interference_range 15
Line 21057: add_property motionalarmsensor deployable_interference_range 0.1
Line 21072: add_property motionalarmsensor interference_range 25
Line 24898: add_property portable_manned_turret deployable_interference_range 2.5
Line 24915: add_property portable_manned_turret interference_range 60
Line 24981: add_property portable_manned_turret shared_interference_range 40
Line 28196: add_property sensor_shield deployable_interference_range 0.1
Line 28205: add_property sensor_shield interference_range 20
Line 29572: add_property spitfire_aa deployable_interference_range 0.1
Line 29584: add_property spitfire_aa interference_range 25
Line 29608: add_property spitfire_aa shared_interference_range 25
Line 29819: add_property spitfire_cloaked deployable_interference_range 0.1
Line 29831: add_property spitfire_cloaked interference_range 25
Line 29855: add_property spitfire_cloaked shared_interference_range 25
Line 29939: add_property spitfire_turret deployable_interference_range 0.1
Line 29951: add_property spitfire_turret interference_range 25
Line 29975: add_property spitfire_turret shared_interference_range 25
Line 30231: add_property stationaryteleportpad deployable_interference_range 5.5
Line 30933: add_property tank_traps deployable_interference_range 3.0
Line 30943: add_property tank_traps interference_range 3.5
Line 30944: add_property tank_traps interference_range2 60
Line 30969: add_property tank_traps shared_interference_range 60
Line 37319: add_property zipline deployable_interference_range 5.5
*/
/**
* Block the deployment of certain entities within a certain distance.
* Deployable vehicles and combat engineer entities both have a deployment condition that can be influenced by these ranges.
* Vehicles of an object type block other vehicles of that object type.
* Combat engineering entities block combat engineering entities of the same category.
* @param main distance between which similar deployable entities block one another (m)
* @param shared na
* @param deployable distance between which this entity may block deployment of other combat engineering entities (m);
* defaults to 0
*/
final case class InterferenceRange(main: Float, shared: Float, deployable: Float = 0f)
object InterferenceRange {
val None: InterferenceRange = InterferenceRange(0f, 0f)
}
/**
* Associate an object's canned in-game representation with its basic game identification unit.
* The extension of this `class` would identify the common data necessary to construct such a given game object.<br>
@ -177,7 +125,7 @@ abstract class ObjectDefinition(private val objectId: Int)
/**
* na
*/
var interference: InterferenceRange = InterferenceRange.None
var interference: InterferenceRange = Interference.AllowAll
def ObjectId: Int = objectId
}

View file

@ -8,6 +8,7 @@ import net.psforever.objects.definition.converter.{FieldTurretConverter, Interna
import net.psforever.objects.equipment.{EffectTarget, TargetValidation}
import net.psforever.objects.geometry.GeometryForm
import net.psforever.objects.geometry.d3.VolumetricGeometry
import net.psforever.objects.serverobject.deploy.InterferenceRange
import net.psforever.objects.serverobject.mount.{MountInfo, SeatDefinition}
import net.psforever.objects.serverobject.turret.{AutoChecks, AutoCooldowns, AutoRanges, Automation, TurretUpgrade}
import net.psforever.objects.vital.{CollisionXYData, CollisionZData, ComplexDeployableResolutions, SimpleResolutions}
@ -40,6 +41,7 @@ object GlobalDefinitionsDeployable {
boomer.DeployCategory = DeployableCategory.Boomers
boomer.DeployTime = Duration.create(1000, "ms")
boomer.deployAnimation = DeployAnimation.Standard
boomer.interference = InterferenceRange(main = 0.2f)
boomer.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.Splash
SympatheticExplosion = true
@ -62,6 +64,7 @@ object GlobalDefinitionsDeployable {
he_mine.Repairable = false
he_mine.DeployTime = Duration.create(1000, "ms")
he_mine.deployAnimation = DeployAnimation.Standard
he_mine.interference = InterferenceRange(main = 7f, sharedGroupId = 1, shared = 7f, deployables = 0.1f)
he_mine.triggerRadius = 3f
he_mine.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.Splash
@ -85,6 +88,7 @@ object GlobalDefinitionsDeployable {
jammer_mine.Repairable = false
jammer_mine.DeployTime = Duration.create(1000, "ms")
jammer_mine.deployAnimation = DeployAnimation.Standard
jammer_mine.interference = InterferenceRange(main = 7f, sharedGroupId = 1, shared = 7f, deployables = 0.1f)
jammer_mine.DetonateOnJamming = false
jammer_mine.triggerRadius = 3f
jammer_mine.innateDamage = new DamageWithPosition {
@ -133,6 +137,7 @@ object GlobalDefinitionsDeployable {
spitfire_turret.DeployTime = Duration.create(5000, "ms")
spitfire_turret.Model = ComplexDeployableResolutions.calculate
spitfire_turret.deployAnimation = DeployAnimation.Standard
spitfire_turret.interference = InterferenceRange(main = 25f, sharedGroupId = 2, shared = 25f, deployables = 0.1f)
spitfire_turret.AutoFire = Automation(
AutoRanges(
detection = 75f,
@ -176,6 +181,7 @@ object GlobalDefinitionsDeployable {
spitfire_cloaked.DeployCategory = DeployableCategory.SmallTurrets
spitfire_cloaked.DeployTime = Duration.create(5000, "ms")
spitfire_cloaked.deployAnimation = DeployAnimation.Standard
spitfire_cloaked.interference = InterferenceRange(main = 25f, sharedGroupId = 2, shared = 25f, deployables = 0.1f)
spitfire_cloaked.Model = ComplexDeployableResolutions.calculate
spitfire_cloaked.AutoFire = Automation(
AutoRanges(
@ -226,6 +232,7 @@ object GlobalDefinitionsDeployable {
spitfire_aa.DeployCategory = DeployableCategory.SmallTurrets
spitfire_aa.DeployTime = Duration.create(5000, "ms")
spitfire_aa.deployAnimation = DeployAnimation.Standard
spitfire_aa.interference = InterferenceRange(main = 25f, sharedGroupId = 2, shared = 25f, deployables = 0.1f)
spitfire_aa.Model = ComplexDeployableResolutions.calculate
spitfire_aa.AutoFire = Automation(
AutoRanges(
@ -263,6 +270,7 @@ object GlobalDefinitionsDeployable {
motionalarmsensor.RepairIfDestroyed = false
motionalarmsensor.DeployTime = Duration.create(1000, "ms")
motionalarmsensor.deployAnimation = DeployAnimation.Standard
motionalarmsensor.interference = InterferenceRange(main = 25f, deployables = 0.1f)
motionalarmsensor.Geometry = sensor
sensor_shield.Name = "sensor_shield"
@ -273,6 +281,7 @@ object GlobalDefinitionsDeployable {
sensor_shield.RepairIfDestroyed = false
sensor_shield.DeployTime = Duration.create(5000, "ms")
sensor_shield.deployAnimation = DeployAnimation.Standard
sensor_shield.interference = InterferenceRange(main = 20f, deployables = 0.1f)
sensor_shield.Geometry = sensor
tank_traps.Name = "tank_traps"
@ -284,6 +293,8 @@ object GlobalDefinitionsDeployable {
tank_traps.DeployCategory = DeployableCategory.TankTraps
tank_traps.DeployTime = Duration.create(6000, "ms")
tank_traps.deployAnimation = DeployAnimation.Fdu
tank_traps.interference = InterferenceRange(main = 3.5f, sharedGroupId = 3, shared = 60f, deployables = 3f)
//todo what is tank_traps interference2 60
//tank_traps do not explode
tank_traps.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.One
@ -318,6 +329,7 @@ object GlobalDefinitionsDeployable {
portable_manned_turret.DeployCategory = DeployableCategory.FieldTurrets
portable_manned_turret.DeployTime = Duration.create(6000, "ms")
portable_manned_turret.deployAnimation = DeployAnimation.Fdu
portable_manned_turret.interference = InterferenceRange(main = 60f, sharedGroupId = 3, shared = 40f, deployables = 2.5f)
portable_manned_turret.Model = ComplexDeployableResolutions.calculate
portable_manned_turret.RadiationShielding = 0.5f
portable_manned_turret.innateDamage = new DamageWithPosition {
@ -351,6 +363,7 @@ object GlobalDefinitionsDeployable {
portable_manned_turret_nc.DeployCategory = DeployableCategory.FieldTurrets
portable_manned_turret_nc.DeployTime = Duration.create(6000, "ms")
portable_manned_turret_nc.deployAnimation = DeployAnimation.Fdu
portable_manned_turret_nc.interference = InterferenceRange(main = 60f, sharedGroupId = 3, shared = 40f, deployables = 2.5f)
portable_manned_turret_nc.Model = ComplexDeployableResolutions.calculate
portable_manned_turret_nc.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.One
@ -383,6 +396,7 @@ object GlobalDefinitionsDeployable {
portable_manned_turret_tr.DeployCategory = DeployableCategory.FieldTurrets
portable_manned_turret_tr.DeployTime = Duration.create(6000, "ms")
portable_manned_turret_tr.deployAnimation = DeployAnimation.Fdu
portable_manned_turret_tr.interference = InterferenceRange(main = 60f, sharedGroupId = 3, shared = 40f, deployables = 2.5f)
portable_manned_turret_tr.Model = ComplexDeployableResolutions.calculate
portable_manned_turret_tr.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.One
@ -415,6 +429,7 @@ object GlobalDefinitionsDeployable {
portable_manned_turret_vs.DeployCategory = DeployableCategory.FieldTurrets
portable_manned_turret_vs.DeployTime = Duration.create(6000, "ms")
portable_manned_turret_vs.deployAnimation = DeployAnimation.Fdu
portable_manned_turret_vs.interference = InterferenceRange(main = 60f, sharedGroupId = 3, shared = 40f, deployables = 2.5f)
portable_manned_turret_vs.Model = ComplexDeployableResolutions.calculate
portable_manned_turret_vs.innateDamage = new DamageWithPosition {
CausesDamageType = DamageType.One
@ -437,6 +452,7 @@ object GlobalDefinitionsDeployable {
deployable_shield_generator.RepairIfDestroyed = false
deployable_shield_generator.DeployTime = Duration.create(6000, "ms")
deployable_shield_generator.deployAnimation = DeployAnimation.Fdu
deployable_shield_generator.interference = InterferenceRange(main = 125f, sharedGroupId = 3, shared = 60f, deployables = 2f)
deployable_shield_generator.Model = ComplexDeployableResolutions.calculate
deployable_shield_generator.Geometry = GeometryForm.representByCylinder(radius = 0.6562f, height = 2.17188f)

View file

@ -6,6 +6,7 @@ import net.psforever.objects.avatar.Certification
import net.psforever.objects.equipment.EffectTarget
import net.psforever.objects.geometry.GeometryForm
import net.psforever.objects.geometry.d3.VolumetricGeometry
import net.psforever.objects.serverobject.deploy.InterferenceRange
import net.psforever.objects.serverobject.doors.InteriorDoorField
import net.psforever.objects.serverobject.mount.{MountInfo, SeatDefinition}
import net.psforever.objects.serverobject.pad.VehicleSpawnPadDefinition
@ -934,5 +935,11 @@ object GlobalDefinitionsMiscellaneous {
obbasemesh.Descriptor = "orbital_shuttle_pad"
obbasemesh.Damageable = false
obbasemesh.Repairable = false
stationaryteleportpad.Name = "stationaryteleportpad"
stationaryteleportpad.interference = InterferenceRange(deployables = 5.5f)
zipline.Name = "zipline"
zipline.interference = InterferenceRange(deployables = 5.5f)
}
}

View file

@ -6,6 +6,7 @@ import net.psforever.objects.definition.converter._
import net.psforever.objects.geometry.GeometryForm
import net.psforever.objects.inventory.InventoryTile
import net.psforever.objects.GlobalDefinitions
import net.psforever.objects.serverobject.deploy.InterferenceRange
import net.psforever.objects.serverobject.mount._
import net.psforever.objects.vehicles.{DestroyedVehicle, UtilityType, VehicleSubsystemEntry}
import net.psforever.objects.vital.base.DamageType
@ -969,6 +970,7 @@ object GlobalDefinitionsVehicle {
ams.Deployment = true
ams.DeployTime = 2000
ams.UndeployTime = 2000
ams.interference = InterferenceRange(main = 125f, sharedGroupId = 3, shared = 30f)
ams.DeconstructionTime = Some(20 minutes)
ams.AutoPilotSpeeds = (18, 6)
ams.Packet = utilityConverter

View file

@ -0,0 +1,94 @@
// Copyright (c) 2024 PSForever
package net.psforever.objects.serverobject.deploy
import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.definition.ObjectDefinition
import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.zones.Zone
import net.psforever.types.{DriveState, Vector3}
/**
* Block the deployment of certain entities within a certain distance.
* Deployable vehicles and combat engineer entities both have a deployment condition that can be influenced by these ranges.
* Vehicles of an object type block other vehicles of that object type.
* Combat engineering entities block combat engineering entities of the same category.
* @param main distance between which this kind of entity blocks itself (m)
* @param sharedGroupId identifier for the similar entity group
* @param shared distance between entities that belong to the similar group block one another (m)
* @param deployables distance between which this entity may block deployment of combat engineering entities (m);
* defaults to 0
*/
final case class InterferenceRange(main: Float = 0f, sharedGroupId: Int = 0, shared: Float = 0f, deployables: Float = 0f) {
assert(
main > -1f && deployables > -1f,
"if set, interference range must be positive non-zero float value"
)
assert(
sharedGroupId == 0 || shared > 0f,
"if set, a shared group of a non-zero id should have a positive non-zero float value"
)
}
object Interference {
final val AllowAll: InterferenceRange = InterferenceRange()
final val MaxRange: Float = 125f
/**
* When two entities connected by similarity or distance exert influence on one another
* that stops the later-acting entity from manifesting
* or disables certain behaviors from the later-acting entity.
* Only dynamic entities are examined.
* Static entities like facility amenities or zone-specific elements that exert interference
* must manage their interactions through other methods.
* @param zone game world in which this test will be conducted;
* entity should be `ZoneAware`, but it may not be set correctly during this part of its internal process
* @param obj entity that may be interfered with
* @return a different entity that causes the test entity to suffer interference
*/
def Test(zone: Zone, obj: PlanetSideGameObject with FactionAffinity): Option[PlanetSideGameObject with FactionAffinity] = {
val (data, filterFunc) = SetupForTest(zone, obj)
data.find(filterFunc)
}
/**
* When two entities connected by similarity or distance exert influence on one another
* that stops the later-acting entity from manifesting
* or disables certain behaviors from the later-acting entity.
* @param zone game world in which this test will be conducted;
* entity should be `ZoneAware`, but it may not be set correctly during this part of its internal process
* @param obj entity that may be interfered with
* @return list of entities to run an interference test on, and
* predicate to determine which entities pass the test
*/
def SetupForTest(
zone: Zone,
obj: PlanetSideGameObject with FactionAffinity
): (List[PlanetSideGameObject with FactionAffinity], PlanetSideGameObject => Boolean) = {
val position = obj.Position
val faction = obj.Faction
val objectDefinition = obj.Definition
val sharedGroupId = objectDefinition.interference.sharedGroupId
val sector = zone.blockMap.sector(position, Interference.MaxRange)
(
(sector.deployableList ++ sector.vehicleList.filter(_.DeploymentState == DriveState.Deployed)).filter(_.Faction == faction),
interferenceTest(position, sharedGroupId != 0, sharedGroupId, objectDefinition)
)
}
private def interferenceTest(
position: Vector3,
inAGroup: Boolean,
sharedGroupId: Int,
objectDefinition: ObjectDefinition
): PlanetSideGameObject => Boolean = { p =>
val pDefinition = p.Definition
val otherInterference = pDefinition.interference
(otherInterference ne Interference.AllowAll) && {
lazy val distanceSq = Vector3.DistanceSquared(position, p.Position).toDouble
(pDefinition == objectDefinition && distanceSq < math.pow(otherInterference.main.toDouble, 2)) ||
(inAGroup && sharedGroupId == otherInterference.sharedGroupId && distanceSq < math.pow(otherInterference.shared.toDouble, 2)) ||
distanceSq < math.pow(otherInterference.deployables.toDouble, 2)
}
}
}

View file

@ -0,0 +1,12 @@
// Copyright (c) 2024 PSForever
package net.psforever.objects.serverobject.zipline
import net.psforever.objects.definition.ObjectDefinition
/**
* The definition for any generic teleportation entity.
* Two entities are described by this object definition - zip lines and the teleportation rings, both in the caverns.
* Entities of these objects are environmental, like facilities, do not get constructed by the user.
* The said entities also do not require being configured at login or zone load.
*/
class GenericTeleportationDefinition(private val objectId: Int) extends ObjectDefinition(objectId)

View file

@ -5,10 +5,10 @@ import akka.actor.Actor
import net.psforever.objects.Player
import net.psforever.actors.zone.ZoneActor
import net.psforever.objects.ce.Deployable
import net.psforever.objects.serverobject.deploy.Interference
import net.psforever.objects.sourcing.ObjectSource
import net.psforever.objects.vehicles.MountedWeapons
import net.psforever.objects.vital.SpawningActivity
import net.psforever.types.Vector3
import scala.annotation.tailrec
import scala.collection.mutable
@ -87,11 +87,11 @@ class ZoneDeployableActor(
obj.ClearHistory()
}
case Zone.Deployable.IsBuilt(_) => ;
case Zone.Deployable.IsBuilt(_) => ()
case Zone.Deployable.IsDismissed(_) => ;
case Zone.Deployable.IsDismissed(_) => ()
case _ => ;
case _ => ()
}
}
@ -102,17 +102,8 @@ object ZoneDeployableActor {
deployableList: ListBuffer[Deployable]
): Boolean = {
val position = obj.Position
val positionxy = position.xy
deployableList.find(d => d == obj) match {
case None if {
val interference = obj.Definition.interference
val category = obj.Definition.DeployCategory
val sector = zone.blockMap.sector(position, interference.main)
!sector.deployableList.exists { p =>
p.Definition.DeployCategory == category ||
Vector3.DistanceSquared(positionxy, p.Position.xy).toDouble < math.pow(p.Definition.interference.deployable.toDouble, 2)
}
} =>
deployableList.find(_ eq obj) match {
case None if Interference.Test(zone, obj).isEmpty =>
deployableList += obj
zone.actor ! ZoneActor.AddToBlockMap(obj, position)
true

View file

@ -15,9 +15,9 @@ object DriveState extends Enumeration {
val Undeploying = Value(1)
val Deploying = Value(2)
val Deployed = Value(3)
val UNK4 = Value(4) // to have Xtoolspar working
val UNK5 = Value(5) // to have Xtoolspar working
val UNK6 = Value(6) // to have Xtoolspar working
val UNK4 = Value(4) // to have decoding tool working
val UNK5 = Value(5) // to have decoding tool working
val UNK6 = Value(6) // to have decoding tool working
val State7 = Value(7) //unknown; not encountered on a vehicle that can deploy; functions like Mobile
val State127 = Value(127) //unknown