Proximity Terminal Fix (#241)

* modifications to ProximityUnit and related classes to internalize the effect control for the terminal, removing the flywheel functiuonality from WSA

* proximity operations for medical terminals (the one in the Anguta lobby, specifically) is functional; some entities besides Player now keep track of the continent they possess, a necessary compromise for proximity ops

* repair rearm silos (Anguta courtyard East) demonstrate operational behavior when lattice benefits are active

* proximity terminals may now juggle multiple targets that move in and out of range and change validity over time

* previous rebase; preparing for special location + offset calculations for utilities

* working location-based proximity repair terminals for the lodestar, utilizing new fields in the vehicle definition, new configuration method in the utilities, and new calculations for Vector3 entities; some comments and tests

* separated ProximityTarget; updated existing terminals; restored defaults; preparing to fix tests

* tests involving the proximity unit workflow

* dismantling a portion of the proximity terminal machinery that is no longer necessary and only poses risk to the system; removing temporary code used to quickly test vehicle silo repairs
This commit is contained in:
Fate-JH 2018-12-23 21:09:12 -05:00 committed by GitHub
parent c4c8609238
commit 961ae1b93b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1320 additions and 888 deletions

View file

@ -18,7 +18,7 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition
import net.psforever.objects.serverobject.turret.{TurretDefinition, TurretUpgrade} import net.psforever.objects.serverobject.turret.{TurretDefinition, TurretUpgrade}
import net.psforever.objects.vehicles.{DestroyedVehicle, SeatArmorRestriction, UtilityType} import net.psforever.objects.vehicles.{DestroyedVehicle, SeatArmorRestriction, UtilityType}
import net.psforever.objects.vital.{DamageType, StandardResolutions} import net.psforever.objects.vital.{DamageType, StandardResolutions}
import net.psforever.types.{CertificationType, PlanetSideEmpire} import net.psforever.types.{CertificationType, PlanetSideEmpire, Vector3}
import scala.collection.mutable import scala.collection.mutable
import scala.concurrent.duration._ import scala.concurrent.duration._
@ -920,9 +920,13 @@ object GlobalDefinitions {
val medical_terminal = new MedicalTerminalDefinition(529) val medical_terminal = new MedicalTerminalDefinition(529)
val pad_landing = new RepairRearmSiloDefinition(719) val portable_med_terminal = new MedicalTerminalDefinition(689)
val repair_silo = new RepairRearmSiloDefinition(729) val pad_landing_frame = new MedicalTerminalDefinition(618)
val pad_landing_tower_frame = new MedicalTerminalDefinition(619)
val repair_silo = new MedicalTerminalDefinition(729)
val spawn_pad = new VehicleSpawnPadDefinition val spawn_pad = new VehicleSpawnPadDefinition
@ -938,33 +942,18 @@ object GlobalDefinitions {
val secondary_capture = new CaptureTerminalDefinition(751) // Tower CC val secondary_capture = new CaptureTerminalDefinition(751) // Tower CC
val lodestar_repair_terminal = new OrderTerminalDefinition { //TODO wrong object class val lodestar_repair_terminal = new MedicalTerminalDefinition(461)
override def ObjectId : Int = 461
}
val multivehicle_rearm_terminal = new _OrderTerminalDefinition(576) { val multivehicle_rearm_terminal = new _OrderTerminalDefinition(576)
Name = "multivehicle_rearm_terminal"
Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
}
val bfr_rearm_terminal = new _OrderTerminalDefinition(142) { val bfr_rearm_terminal = new _OrderTerminalDefinition(142)
Name = "bfr_rearm_terminal"
Page += 3 -> _OrderTerminalDefinition.EquipmentPage(Map.empty[String, ()=>Equipment]) //TODO add stock to page
Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
}
val manned_turret = new TurretDefinition(480) { val air_rearm_terminal = new _OrderTerminalDefinition(42)
Name = "manned_turret"
MaxHealth = 3600 val ground_rearm_terminal = new _OrderTerminalDefinition(384)
Weapons += 1 -> new mutable.HashMap()
Weapons(1) += TurretUpgrade.None -> phalanx_sgl_hevgatcan val manned_turret = new TurretDefinition(480)
Weapons(1) += TurretUpgrade.AVCombo -> phalanx_avcombo initMiscellaneous()
Weapons(1) += TurretUpgrade.FlakCombo -> phalanx_flakcombo
MountPoints += 1 -> 0
FactionLocked = true
ReserveAmmunition = false
}
/** /**
* Given a faction, provide the standard assault melee weapon. * Given a faction, provide the standard assault melee weapon.
@ -5411,7 +5400,9 @@ object GlobalDefinitions {
lodestar.MountPoints += 2 -> 1 lodestar.MountPoints += 2 -> 1
lodestar.Cargo += 1 -> new CargoDefinition() lodestar.Cargo += 1 -> new CargoDefinition()
lodestar.Utilities += 2 -> UtilityType.lodestar_repair_terminal lodestar.Utilities += 2 -> UtilityType.lodestar_repair_terminal
lodestar.UtilityOffset += 2 -> Vector3(0, 20, 0)
lodestar.Utilities += 3 -> UtilityType.lodestar_repair_terminal lodestar.Utilities += 3 -> UtilityType.lodestar_repair_terminal
lodestar.UtilityOffset += 3 -> Vector3(0, -20, 0)
lodestar.Utilities += 4 -> UtilityType.multivehicle_rearm_terminal lodestar.Utilities += 4 -> UtilityType.multivehicle_rearm_terminal
lodestar.Utilities += 5 -> UtilityType.multivehicle_rearm_terminal lodestar.Utilities += 5 -> UtilityType.multivehicle_rearm_terminal
lodestar.Utilities += 6 -> UtilityType.bfr_rearm_terminal lodestar.Utilities += 6 -> UtilityType.bfr_rearm_terminal
@ -5599,4 +5590,92 @@ object GlobalDefinitions {
internal_router_telepad_deployable.DeployTime = Duration.create(1, "ms") internal_router_telepad_deployable.DeployTime = Duration.create(1, "ms")
internal_router_telepad_deployable.Packet = new InternalTelepadDeployableConverter internal_router_telepad_deployable.Packet = new InternalTelepadDeployableConverter
} }
/**
* Initialize `Miscellaneous` globals.
*/
private def initMiscellaneous() : Unit = {
adv_med_terminal.Name = "adv_med_terminal"
adv_med_terminal.Interval = 500
adv_med_terminal.HealAmount = 8
adv_med_terminal.ArmorAmount = 15
adv_med_terminal.UseRadius = 0.75f
adv_med_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical
crystals_health_a.Name = "crystals_health_a"
crystals_health_a.Interval = 500
crystals_health_a.HealAmount = 4
crystals_health_a.UseRadius = 5
crystals_health_a.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.HealthCrystal
crystals_health_b.Name = "crystals_health_b"
crystals_health_b.Interval = 500
crystals_health_b.HealAmount = 4
crystals_health_b.UseRadius = 1.3f
crystals_health_b.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.HealthCrystal
medical_terminal.Name = "medical_terminal"
medical_terminal.Interval = 500
medical_terminal.HealAmount = 5
medical_terminal.ArmorAmount = 10
medical_terminal.UseRadius = 0.75f
medical_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical
portable_med_terminal.Name = "portable_med_terminal"
portable_med_terminal.Interval = 500
portable_med_terminal.HealAmount = 5
portable_med_terminal.ArmorAmount = 10
portable_med_terminal.UseRadius = 3
portable_med_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical
pad_landing_frame.Name = "pad_landing_frame"
pad_landing_frame.Interval = 1000
pad_landing_frame.HealAmount = 60
pad_landing_frame.UseRadius = 20
pad_landing_frame.TargetValidation += ProximityTarget.Aircraft -> ProximityTerminalControl.Validation.PadLanding
pad_landing_tower_frame.Name = "pad_landing_tower_frame"
pad_landing_tower_frame.Interval = 1000
pad_landing_tower_frame.HealAmount = 60
pad_landing_tower_frame.UseRadius = 20
pad_landing_tower_frame.TargetValidation += ProximityTarget.Aircraft -> ProximityTerminalControl.Validation.PadLanding
repair_silo.Name = "repair_silo"
repair_silo.Interval = 1000
repair_silo.HealAmount = 60
repair_silo.UseRadius = 20
repair_silo.TargetValidation += ProximityTarget.Vehicle -> ProximityTerminalControl.Validation.RepairSilo
lodestar_repair_terminal.Name = "lodestar_repair_terminal"
lodestar_repair_terminal.Interval = 1000
lodestar_repair_terminal.HealAmount = 60
lodestar_repair_terminal.UseRadius = 20
lodestar_repair_terminal.TargetValidation += ProximityTarget.Vehicle -> ProximityTerminalControl.Validation.RepairSilo
multivehicle_rearm_terminal.Name = "multivehicle_rearm_terminal"
multivehicle_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
multivehicle_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
bfr_rearm_terminal.Name = "bfr_rearm_terminal"
bfr_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(Map.empty[String, ()=>Equipment]) //TODO add stock to page
bfr_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
air_rearm_terminal.Name = "air_rearm_terminal"
air_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
air_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
ground_rearm_terminal.Name = "ground_rearm_terminal"
ground_rearm_terminal.Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
ground_rearm_terminal.Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
manned_turret.Name = "manned_turret"
manned_turret.MaxHealth = 3600
manned_turret.Weapons += 1 -> new mutable.HashMap()
manned_turret.Weapons(1) += TurretUpgrade.None -> phalanx_sgl_hevgatcan
manned_turret.Weapons(1) += TurretUpgrade.AVCombo -> phalanx_avcombo
manned_turret.Weapons(1) += TurretUpgrade.FlakCombo -> phalanx_flakcombo
manned_turret.MountPoints += 1 -> 0
manned_turret.FactionLocked = true
manned_turret.ReserveAmmunition = false
}
} }

View file

@ -8,6 +8,7 @@ import net.psforever.objects.loadouts.Loadout
import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.vital.resistance.ResistanceProfile import net.psforever.objects.vital.resistance.ResistanceProfile
import net.psforever.objects.vital.{DamageResistanceModel, Vitality} import net.psforever.objects.vital.{DamageResistanceModel, Vitality}
import net.psforever.objects.zones.ZoneAware
import net.psforever.packet.game.PlanetSideGUID import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types._ import net.psforever.types._
@ -18,7 +19,8 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
with FactionAffinity with FactionAffinity
with Vitality with Vitality
with ResistanceProfile with ResistanceProfile
with Container { with Container
with ZoneAware {
private var alive : Boolean = false private var alive : Boolean = false
private var backpack : Boolean = false private var backpack : Boolean = false
private var health : Int = 0 private var health : Int = 0

View file

@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects package net.psforever.objects
import akka.actor.ActorRef
import net.psforever.objects.definition.VehicleDefinition import net.psforever.objects.definition.VehicleDefinition
import net.psforever.objects.equipment.{Equipment, EquipmentSize} import net.psforever.objects.equipment.{Equipment, EquipmentSize}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile} import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile}
@ -10,6 +11,7 @@ import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.serverobject.deploy.Deployment import net.psforever.objects.serverobject.deploy.Deployment
import net.psforever.objects.vehicles._ import net.psforever.objects.vehicles._
import net.psforever.objects.vital.{DamageResistanceModel, StandardResistanceProfile, Vitality} import net.psforever.objects.vital.{DamageResistanceModel, StandardResistanceProfile, Vitality}
import net.psforever.objects.zones.ZoneAware
import net.psforever.packet.game.PlanetSideGUID import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.PlanetSideEmpire import net.psforever.types.PlanetSideEmpire
@ -65,6 +67,7 @@ import scala.annotation.tailrec
*/ */
class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServerObject class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServerObject
with FactionAffinity with FactionAffinity
with ZoneAware
with Mountable with Mountable
with MountedWeapons with MountedWeapons
with Deployment with Deployment
@ -80,6 +83,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
private var jammered : Boolean = false private var jammered : Boolean = false
private var cloaked : Boolean = false private var cloaked : Boolean = false
private var capacitor : Int = 0 private var capacitor : Int = 0
private var continent : String = "home2" //the zone id
/** /**
* Permissions control who gets to access different parts of the vehicle; * Permissions control who gets to access different parts of the vehicle;
@ -513,6 +517,32 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
*/ */
def Definition : VehicleDefinition = vehicleDef def Definition : VehicleDefinition = vehicleDef
override def Continent : String = continent
override def Continent_=(zoneId : String) : String = {
continent = zoneId
Continent
}
def canEqual(other: Any): Boolean = other.isInstanceOf[Vehicle]
override def equals(other : Any) : Boolean = other match {
case that: Vehicle =>
(that canEqual this) &&
hashCode() == that.hashCode()
case _ =>
false
}
override def hashCode() : Int = {
Actor match {
case ActorRef.noSender =>
super.hashCode()
case actor =>
actor.hashCode()
}
}
/** /**
* Override the string representation to provide additional information. * Override the string representation to provide additional information.
* @return the string output * @return the string output
@ -600,7 +630,12 @@ object Vehicle {
vehicle.cargoHolds = vdef.Cargo.map({ case(num, definition) => num -> Cargo(definition)}).toMap vehicle.cargoHolds = vdef.Cargo.map({ case(num, definition) => num -> Cargo(definition)}).toMap
//create utilities //create utilities
vehicle.utilities = vdef.Utilities.map({ case(num, util) => num -> Utility(util, vehicle) }).toMap vehicle.utilities = vdef.Utilities.map({
case(num, util) =>
val obj = Utility(util, vehicle)
obj().LocationOffset = vdef.UtilityOffset.get(num)
num -> obj
}).toMap
//trunk //trunk
vdef.TrunkSize match { vdef.TrunkSize match {
case InventoryTile.None => ; case InventoryTile.None => ;

View file

@ -6,6 +6,7 @@ import net.psforever.objects.inventory.InventoryTile
import net.psforever.objects.vehicles.{DestroyedVehicle, UtilityType} import net.psforever.objects.vehicles.{DestroyedVehicle, UtilityType}
import net.psforever.objects.vital._ import net.psforever.objects.vital._
import net.psforever.objects.vital.resistance.ResistanceProfileMutators import net.psforever.objects.vital.resistance.ResistanceProfileMutators
import net.psforever.types.Vector3
import scala.collection.mutable import scala.collection.mutable
import scala.concurrent.duration._ import scala.concurrent.duration._
@ -29,6 +30,7 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId)
private val weapons : mutable.HashMap[Int, ToolDefinition] = mutable.HashMap[Int, ToolDefinition]() private val weapons : mutable.HashMap[Int, ToolDefinition] = mutable.HashMap[Int, ToolDefinition]()
private var deployment : Boolean = false private var deployment : Boolean = false
private val utilities : mutable.HashMap[Int, UtilityType.Value] = mutable.HashMap() private val utilities : mutable.HashMap[Int, UtilityType.Value] = mutable.HashMap()
private val utilityOffsets : mutable.HashMap[Int, Vector3] = mutable.HashMap()
private var deploymentTime_Deploy : Int = 0 //ms private var deploymentTime_Deploy : Int = 0 //ms
private var deploymentTime_Undeploy : Int = 0 //ms private var deploymentTime_Undeploy : Int = 0 //ms
private var trunkSize : InventoryTile = InventoryTile.None private var trunkSize : InventoryTile = InventoryTile.None
@ -88,9 +90,10 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId)
Deployment Deployment
} }
def Utilities : mutable.HashMap[Int, UtilityType.Value] = utilities def Utilities : mutable.HashMap[Int, UtilityType.Value] = utilities
def UtilityOffset : mutable.HashMap[Int, Vector3] = utilityOffsets
def DeployTime : Int = deploymentTime_Deploy def DeployTime : Int = deploymentTime_Deploy
def DeployTime_=(dtime : Int) : Int = { def DeployTime_=(dtime : Int) : Int = {

View file

@ -1,12 +1,12 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject package net.psforever.objects.serverobject
import net.psforever.objects.Player import net.psforever.objects.{PlanetSideGameObject, Player}
//temporary location for these messages //temporary location for these messages
object CommonMessages { object CommonMessages {
final case class Use(player : Player) final case class Use(player : Player, data : Option[Any] = None)
final case class Unuse(player : Player) final case class Unuse(player : Player, data : Option[Any] = None)
final case class Hack(player : Player) final case class Hack(player : Player)
final case class ClearHack() final case class ClearHack()
} }

View file

@ -4,12 +4,15 @@ package net.psforever.objects.serverobject
import akka.actor.ActorRef import akka.actor.ActorRef
import net.psforever.objects.PlanetSideGameObject import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.zones.ZoneAware
/** /**
* An object layered on top of the standard game object class that maintains an internal `ActorRef`. * An object layered on top of the standard game object class that maintains an internal `ActorRef`.
* A measure of synchronization can be managed using this `Actor`. * A measure of synchronization can be managed using this `Actor`.
*/ */
abstract class PlanetSideServerObject extends PlanetSideGameObject with FactionAffinity { abstract class PlanetSideServerObject extends PlanetSideGameObject
with FactionAffinity
with ZoneAware {
private var actor = ActorRef.noSender private var actor = ActorRef.noSender
/** /**
@ -30,4 +33,8 @@ abstract class PlanetSideServerObject extends PlanetSideGameObject with Faction
} }
actor actor
} }
def Continent : String = "nowhere"
def Continent_=(zone : String) = Continent
} }

View file

@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.structures package net.psforever.objects.serverobject.structures
import net.psforever.objects.Vehicle
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.types.PlanetSideEmpire import net.psforever.types.{PlanetSideEmpire, Vector3}
/** /**
* Amenities are elements of the game that belong to other elements of the game.<br> * Amenities are elements of the game that belong to other elements of the game.<br>
@ -15,7 +16,10 @@ import net.psforever.types.PlanetSideEmpire
* @see `FactionAffinity` * @see `FactionAffinity`
*/ */
abstract class Amenity extends PlanetSideServerObject { abstract class Amenity extends PlanetSideServerObject {
/** what other entity has authority over this amenity; usually either a building or a vehicle */
private var owner : PlanetSideServerObject = Building.NoBuilding private var owner : PlanetSideServerObject = Building.NoBuilding
/** if the entity exists at a specific position relative to the owner's position */
private var offset : Option[Vector3] = None
def Faction : PlanetSideEmpire.Value = Owner.Faction def Faction : PlanetSideEmpire.Value = Owner.Faction
@ -36,6 +40,26 @@ abstract class Amenity extends PlanetSideServerObject {
owner = obj.asInstanceOf[PlanetSideServerObject] owner = obj.asInstanceOf[PlanetSideServerObject]
Owner Owner
} }
def LocationOffset : Vector3 = offset.getOrElse(Vector3.Zero)
def LocationOffset_=(off : Vector3) : Vector3 = LocationOffset_=(Some(off))
def LocationOffset_=(off : Option[Vector3]) : Vector3 = {
off match {
case Some(Vector3.Zero) =>
offset = None
case _ =>
offset = off
}
LocationOffset
}
override def Continent = Owner match {
case o : Building => o.Zone.Id
case o : Vehicle => o.Continent
case _ => super.Continent
}
} }
object Amenity { object Amenity {

View file

@ -48,6 +48,10 @@ class Building(private val mapId : Int, private val zone : Zone, private val bui
def BuildingType : StructureType.Value = buildingType def BuildingType : StructureType.Value = buildingType
override def Continent : String = zone.Id
override def Continent_=(zone : String) : String = Continent
def Definition: ObjectDefinition = Building.BuildingDefinition def Definition: ObjectDefinition = Building.BuildingDefinition
} }

View file

@ -1,28 +1,40 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import scala.concurrent.duration.{Duration, FiniteDuration}
/** /**
* The definition for any `Terminal` that is of a type "medical_terminal". * The definition for any `Terminal` that is of a type "medical_terminal".
* This includes the functionality of the formal medical terminals and some of the cavern crystals. * This includes the functionality of the formal medical terminals and some of the cavern crystals.
* Do not confuse the game's internal "medical_terminal" object category and the actual `medical_terminal` object (529). * Do not confuse the game's internal "medical_terminal" object category and the actual `medical_terminal` object (529).
*/ */
class MedicalTerminalDefinition(objectId : Int) extends TerminalDefinition(objectId) with ProximityDefinition { class MedicalTerminalDefinition(objectId : Int) extends TerminalDefinition(objectId) with ProximityDefinition {
Name = if(objectId == 38) { private var interval : FiniteDuration = Duration(0, "seconds")
"adv_med_terminal" private var healAmount : Int = 0
private var armorAmount : Int = 0
def Interval : FiniteDuration = interval
def Interval_=(amount : Int) : FiniteDuration = {
Interval_=(Duration(amount, "milliseconds"))
} }
else if(objectId == 225) {
"crystals_health_a" def Interval_=(amount : FiniteDuration) : FiniteDuration = {
interval = amount
Interval
} }
else if(objectId == 226) {
"crystals_health_b" def HealAmount : Int = healAmount
def HealAmount_=(amount : Int) : Int = {
healAmount = amount
HealAmount
} }
else if(objectId == 529) {
"medical_terminal" def ArmorAmount : Int = armorAmount
}
else if(objectId == 689) { def ArmorAmount_=(amount : Int) : Int = {
"portable_med_terminal" armorAmount = amount
} ArmorAmount
else {
throw new IllegalArgumentException("medical terminal must be either object id 38, 225, 226, 529, or 689")
} }
} }

View file

@ -1,9 +1,11 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import net.psforever.objects.Player import net.psforever.objects.{PlanetSideGameObject, Player}
import net.psforever.packet.game.ItemTransactionMessage import net.psforever.packet.game.ItemTransactionMessage
import scala.collection.mutable
/** /**
* The definition for any `Terminal` that possesses a proximity-based effect. * The definition for any `Terminal` that possesses a proximity-based effect.
* This includes the limited proximity-based functionality of the formal medical terminals * This includes the limited proximity-based functionality of the formal medical terminals
@ -11,5 +13,30 @@ import net.psforever.packet.game.ItemTransactionMessage
* Objects created by this definition being linked by their use of `ProximityTerminalUseMessage`. * Objects created by this definition being linked by their use of `ProximityTerminalUseMessage`.
*/ */
trait ProximityDefinition { trait ProximityDefinition {
private var useRadius : Float = 0f //TODO belongs on a wider range of object definitions
private val targetValidation : mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean] = new mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean]()
def UseRadius : Float = useRadius
def UseRadius_=(radius : Float) : Float = {
useRadius = radius
UseRadius
}
def TargetValidation : mutable.HashMap[ProximityTarget.Value, (PlanetSideGameObject)=>Boolean] = targetValidation
def Validations : Seq[(PlanetSideGameObject)=>Boolean] = {
targetValidation.headOption match {
case Some(_) =>
targetValidation.values.toSeq
case None =>
Seq(ProximityDefinition.Invalid)
}
}
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal() def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
} }
object ProximityDefinition {
protected val Invalid : (PlanetSideGameObject=>Boolean) = (_ : PlanetSideGameObject) => false
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
/**
* A classification of the target of this terminal's interactions.
* Arbitrary, but useful.
*/
object ProximityTarget extends Enumeration {
val
Aircraft,
Equipment,
Player,
Vehicle
= Value
}

View file

@ -1,6 +1,10 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.types.Vector3
import services.Service
/** /**
* A server object that is a "terminal" that can be accessed for amenities and services, * A server object that is a "terminal" that can be accessed for amenities and services,
* triggered when a certain distance from the unit itself (proximity-based).<br> * triggered when a certain distance from the unit itself (proximity-based).<br>
@ -35,4 +39,33 @@ object ProximityTerminal {
obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), s"${tdef.Name}_$id") obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), s"${tdef.Name}_$id")
obj obj
} }
/**
* Instantiate an configure a `Terminal` object, with position coordinates.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
* @param id the unique id that will be assigned to this entity
* @param context a context to allow the object to properly set up `ActorSystem` functionality
* @return the `Terminal` object
*/
def Constructor(tdef : TerminalDefinition with ProximityDefinition, pos : Vector3)(id : Int, context : ActorContext) : Terminal = {
import akka.actor.Props
val obj = ProximityTerminal(tdef)
obj.Position = pos
obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), s"${tdef.Name}_$id")
obj
}
/**
* Assemble some logic for a provided owned object after both it ands its owner have been constructed.
* @param obj an `Amenity` object;
* anticipating a `Terminal` object using this same definition
* @param context hook to the local `Actor` system
*/
def Setup(obj : Amenity, context : ActorContext) : Unit = {
import akka.actor.{ActorRef, Props}
if(obj.Actor == ActorRef.noSender) {
obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
obj.Actor ! Service.Startup()
}
}
} }

View file

@ -1,9 +1,14 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import akka.actor.Actor import akka.actor.{Actor, ActorRef, Cancellable}
import net.psforever.objects._
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
import services.{Service, ServiceManager}
import scala.collection.mutable
import scala.concurrent.duration._
/** /**
* An `Actor` that handles messages being dispatched to a specific `ProximityTerminal`. * An `Actor` that handles messages being dispatched to a specific `ProximityTerminal`.
@ -11,21 +16,155 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi
* it returns the same type of messages - wrapped in a `TerminalMessage` - to the `sender`. * it returns the same type of messages - wrapped in a `TerminalMessage` - to the `sender`.
* @param term the proximity unit (terminal) * @param term the proximity unit (terminal)
*/ */
class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor with FactionAffinityBehavior.Check with ProximityUnit.Use { class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor with FactionAffinityBehavior.Check {
var service : ActorRef = ActorRef.noSender
var terminalAction : Cancellable = DefaultCancellable.obj
val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]()
val log = org.log4s.getLogger
def FactionObject : FactionAffinity = term def FactionObject : FactionAffinity = term
def TerminalObject : Terminal with ProximityUnit = term def TerminalObject : Terminal with ProximityUnit = term
def receive : Receive = checkBehavior def receive : Receive = Start
.orElse(proximityBehavior)
def Start : Receive = checkBehavior
.orElse { .orElse {
case Service.Startup() =>
ServiceManager.serviceManager ! ServiceManager.Lookup("local")
case ServiceManager.LookupResult("local", ref) =>
service = ref
context.become(Run)
case _ => ;
}
def Run : Receive = checkBehavior
.orElse {
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
Use(target, term.Continent, sender)
}
case CommonMessages.Use(_, Some((target : PlanetSideGameObject, callback : ActorRef))) =>
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
Use(target, term.Continent, callback)
}
case CommonMessages.Use(_, _) =>
log.warn(s"unexpected format for CommonMessages.Use in this context")
case CommonMessages.Unuse(_, Some(target : PlanetSideGameObject)) =>
Unuse(target, term.Continent)
case CommonMessages.Unuse(_, _) =>
log.warn(s"unexpected format for CommonMessages.Unuse in this context")
case ProximityTerminalControl.TerminalAction() =>
val proxDef = term.Definition.asInstanceOf[ProximityDefinition]
val validateFunc : PlanetSideGameObject=>Boolean = term.Validate(proxDef.UseRadius * proxDef.UseRadius, proxDef.Validations)
val callbackList = callbacks.toList
term.Targets.zipWithIndex.foreach({ case((target, index)) =>
if(validateFunc(target)) {
callbackList.lift(index) match {
case Some(cback) =>
cback ! ProximityUnit.Action(term, target)
case None =>
log.error(s"improper callback registered for $target on $term in zone ${term.Owner.Continent}; this may be recoverable")
}
}
else {
Unuse(target, term.Continent)
}
})
case CommonMessages.Hack(player) => case CommonMessages.Hack(player) =>
term.HackedBy = player term.HackedBy = player
sender ! true sender ! true
case CommonMessages.ClearHack() => case CommonMessages.ClearHack() =>
term.HackedBy = None term.HackedBy = None
case _ => ;
case ProximityUnit.Action(_, _) =>
//reserved
case msg =>
log.warn(s"unexpected message $msg")
} }
def Use(target : PlanetSideGameObject, zone : String, callback : ActorRef) : Unit = {
val hadNoUsers = term.NumberUsers == 0
if(term.AddUser(target)) {
log.info(s"ProximityTerminal.Use: unit ${term.Definition.Name}@${term.GUID.guid} will act on $target")
//add callback
callbacks += callback
//activation
if(term.NumberUsers == 1 && hadNoUsers) {
val medDef = term.Definition.asInstanceOf[MedicalTerminalDefinition]
import scala.concurrent.ExecutionContext.Implicits.global
terminalAction.cancel
terminalAction = context.system.scheduler.schedule(500 milliseconds, medDef.Interval, self, ProximityTerminalControl.TerminalAction())
service ! Terminal.StartProximityEffect(term)
}
}
else {
log.warn(s"ProximityTerminal.Use: $target was rejected by unit ${term.Definition.Name}@${term.GUID.guid}")
}
}
def Unuse(target : PlanetSideGameObject, zone : String) : Unit = {
val whereTarget = term.Targets.indexWhere(_ eq target)
val previousUsers = term.NumberUsers
val hadUsers = previousUsers > 0
if(whereTarget > -1 && term.RemoveUser(target)) {
log.info(s"ProximityTerminal.Unuse: unit ${term.Definition.Name}@${term.GUID.guid} will cease operation on $target")
//remove callback
callbacks.remove(whereTarget)
//de-activation (global / local)
if(term.NumberUsers == 0 && hadUsers) {
terminalAction.cancel
service ! Terminal.StopProximityEffect(term)
}
}
else {
log.debug(s"ProximityTerminal.Unuse: target by proximity $target is not known to $term, though the unit tried to 'Unuse' it")
}
}
override def toString : String = term.Definition.Name override def toString : String = term.Definition.Name
} }
object ProximityTerminalControl {
object Validation {
def Medical(target : PlanetSideGameObject) : Boolean = target match {
case p : Player =>
p.Health > 0 && (p.Health < p.MaxHealth || p.Armor < p.MaxArmor)
case _ =>
false
}
def HealthCrystal(target : PlanetSideGameObject) : Boolean = target match {
case p : Player =>
p.Health > 0 && p.Health < p.MaxHealth
case _ =>
false
}
def RepairSilo(target : PlanetSideGameObject) : Boolean = target match {
case v : Vehicle =>
!GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth
case _ =>
false
}
def PadLanding(target : PlanetSideGameObject) : Boolean = target match {
case v : Vehicle =>
GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth
case _ =>
false
}
}
private case class TerminalAction()
}

View file

@ -1,9 +1,10 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.serverobject.terminals.Terminal.TerminalMessage import net.psforever.types.Vector3
import net.psforever.packet.game.PlanetSideGUID
import scala.collection.mutable
/** /**
* A server object that provides a service, triggered when a certain distance from the unit itself (proximity-based). * A server object that provides a service, triggered when a certain distance from the unit itself (proximity-based).
@ -16,45 +17,78 @@ trait ProximityUnit {
/** /**
* A list of targets that are currently affected by this proximity unit. * A list of targets that are currently affected by this proximity unit.
*/ */
private var targets : Set[PlanetSideGUID] = Set.empty private var targets : mutable.ListBuffer[PlanetSideGameObject] = mutable.ListBuffer[PlanetSideGameObject]()
def Targets : Seq[PlanetSideGameObject] = targets toList
def NumberUsers : Int = targets.size def NumberUsers : Int = targets.size
def AddUser(player_guid : PlanetSideGUID) : Int = { /**
targets += player_guid * Accept a new target for this unit.
NumberUsers * @param target the new target
* @return `true`, if the entrant has been added and is new to the list;
* `false` if the entrant is already in the list or can not be added
*/
def AddUser(target : PlanetSideGameObject) : Boolean = {
val alreadyContains = targets.contains(target)
if(!alreadyContains) {
targets += target
targets.contains(target)
}
else {
false
}
} }
def RemoveUser(player_guid : PlanetSideGUID) : Int = { /**
targets -= player_guid * Remove an existing target for this unit.
NumberUsers * @param target the target
* @return `true`, if the submitted entity was previously in the list but is not longer in the list;
* `false`, if the submitted entity was never in the list or can not be removed
*/
def RemoveUser(target : PlanetSideGameObject) : Boolean = {
val alreadyContains = targets.contains(target)
if(alreadyContains) {
targets -= target
!targets.contains(target)
}
else {
false
}
}
/**
* Confirm whether the entity is a valid target for the effects of this unit.
* @param target the submitted entity
* @return `true`, if the entity passes the validation tests;
* `false`, otherwise
*/
def Validate(target : PlanetSideGameObject) : Boolean = {
val proxDef = Definition.asInstanceOf[ProximityDefinition]
val radius = proxDef.UseRadius * proxDef.UseRadius
val validation = proxDef.Validations
Validate(radius, validation)(target)
}
/**
* Confirm whether the entity is a valid target for the effects of this unit.
* Curried to accept parameters for the tests separately from the entity to be tested.
* In general, the two requirements beyond the custom validations involve
* distance (from the unit)
* and inclusiveness (known to the unit beforehand).
* @param radius the squared minimum activation distance
* @param validations the custom tests that the entity must pass to be considered valid;
* in general, regardless of the type of the target, any of the tests must be passed
* @param target the submitted entity
* @return `true`, if the entity passes the validation tests;
* `false`, otherwise
*/
def Validate(radius : Float, validations : Seq[(PlanetSideGameObject)=>Boolean])(target : PlanetSideGameObject) : Boolean = {
//org.log4s.getLogger("ProximityUnit").info(s"vehicle: ${Owner.Position}, terminal: $Position, target: ${target.Position}, toOwner: ${Vector3.Distance(Position, Owner.Position)}, toTarget: ${Vector3.Distance(Position, target.Position)}")
targets.contains(target) && Vector3.DistanceSquared(Position, target.Position) <= radius && validations.exists(p => p(target))
} }
} }
object ProximityUnit { object ProximityUnit {
import akka.actor.Actor final case class Action(terminal : Terminal with ProximityUnit, target : PlanetSideGameObject)
/**
* A mixin `trait` for an `Actor`'s `PartialFunction` that handles messages,
* in this case handling messages that controls the telegraphed state of the `ProximityUnit` object as the number of users changes.
*/
trait Use {
this : Actor =>
def TerminalObject : Terminal with ProximityUnit
val proximityBehavior : Receive = {
case CommonMessages.Use(player) =>
val hadNoUsers = TerminalObject.NumberUsers == 0
if(TerminalObject.AddUser(player.GUID) == 1 && hadNoUsers) {
sender ! TerminalMessage(player, null, Terminal.StartProximityEffect(TerminalObject))
}
case CommonMessages.Unuse(player) =>
val hadUsers = TerminalObject.NumberUsers > 0
if(TerminalObject.RemoveUser(player.GUID) == 0 && hadUsers) {
sender ! TerminalMessage(player, null, Terminal.StopProximityEffect(TerminalObject))
}
}
}
} }

View file

@ -1,44 +0,0 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
import net.psforever.objects.Player
import net.psforever.objects.inventory.InventoryItem
import net.psforever.objects.loadouts.VehicleLoadout
import net.psforever.objects.serverobject.terminals.EquipmentTerminalDefinition.BuildSimplifiedPattern
import net.psforever.packet.game.ItemTransactionMessage
/**
* The `Definition` for any `Terminal` that is of a type "repair_silo."
* Has both proximity-based operation and direct access purchasing power.
*/
class RepairRearmSiloDefinition(objectId : Int) extends EquipmentTerminalDefinition(objectId) with ProximityDefinition {
Name = if(objectId == 719) {
"pad_landing"
}
else if(objectId == 729) {
"repair_silo"
}
else {
throw new IllegalArgumentException("repair re-arm terminal must be either object id 719 or 729")
}
private val buyFunc : (Player, ItemTransactionMessage)=>Terminal.Exchange = EquipmentTerminalDefinition.Buy(Map.empty, Map.empty, Map.empty)
override def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = buyFunc(player, msg)
override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
if(msg.item_page == 4) { //Favorites tab
player.LoadLoadout(msg.unk1 + 10) match {
case Some(loadout : VehicleLoadout) =>
val weapons = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
val inventory = loadout.inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
Terminal.VehicleLoadout(loadout.vehicle_definition, weapons, inventory)
case _ =>
Terminal.NoDeal()
}
}
else {
Terminal.NoDeal()
}
}
}

View file

@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.objects.serverobject.terminals._ import net.psforever.objects.serverobject.terminals._
import net.psforever.objects.serverobject.tube.{SpawnTube, SpawnTubeDefinition} import net.psforever.objects.serverobject.tube.{SpawnTube, SpawnTubeDefinition}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID} import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types.Vector3
/** /**
* An `Enumeration` of the available vehicular utilities.<br> * An `Enumeration` of the available vehicular utilities.<br>
@ -78,6 +79,28 @@ class Utility(util : UtilityType.Value, vehicle : Vehicle) {
object Utility { object Utility {
type UtilLogic = (Amenity, ActorContext)=>Unit type UtilLogic = (Amenity, ActorContext)=>Unit
/**
* Embedded (owned) entities are known in relation to their parent entity.
* These overrides to the `Position` method and the `Orientation` method reflect this.
*/
sealed trait UtilityWorldEntity {
this : Amenity =>
override def Position : Vector3 = {
val oPos = Owner.Position
(Owner, LocationOffset) match {
case (_, Vector3.Zero) =>
oPos
case (_ : Vehicle, v) =>
oPos + v.Rz(Orientation.z + 90)
case _ =>
oPos
}
}
override def Orientation : Vector3 = Owner.Orientation
}
/** /**
* Overloaded constructor. * Overloaded constructor.
* @param util the type of the `Amenity` object to be created * @param util the type of the `Amenity` object to be created
@ -99,7 +122,7 @@ object Utility {
case UtilityType.bfr_rearm_terminal => case UtilityType.bfr_rearm_terminal =>
new TerminalUtility(GlobalDefinitions.bfr_rearm_terminal) new TerminalUtility(GlobalDefinitions.bfr_rearm_terminal)
case UtilityType.lodestar_repair_terminal => case UtilityType.lodestar_repair_terminal =>
new TerminalUtility(GlobalDefinitions.lodestar_repair_terminal) new ProximityTerminalUtility(GlobalDefinitions.lodestar_repair_terminal)
case UtilityType.matrix_terminalc => case UtilityType.matrix_terminalc =>
new TerminalUtility(GlobalDefinitions.matrix_terminalc) new TerminalUtility(GlobalDefinitions.matrix_terminalc)
case UtilityType.multivehicle_rearm_terminal => case UtilityType.multivehicle_rearm_terminal =>
@ -118,22 +141,27 @@ object Utility {
* Override for `SpawnTube` objects so that they inherit the spatial characteristics of their `Owner`. * Override for `SpawnTube` objects so that they inherit the spatial characteristics of their `Owner`.
* @param tubeDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields * @param tubeDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/ */
class SpawnTubeUtility(tubeDef : SpawnTubeDefinition) extends SpawnTube(tubeDef) { class SpawnTubeUtility(tubeDef : SpawnTubeDefinition) extends SpawnTube(tubeDef) with UtilityWorldEntity
override def Position = Owner.Position
override def Orientation = Owner.Orientation
}
/** /**
* Override for `Terminal` objects so that they inherit the spatial characteristics of their `Owner`. * Override for a `Terminal` object so that it inherits the spatial characteristics of its `Owner`.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields * @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/ */
class TerminalUtility(tdef : TerminalDefinition) extends Terminal(tdef) { class TerminalUtility(tdef : TerminalDefinition) extends Terminal(tdef) with UtilityWorldEntity
override def Position = Owner.Position
override def Orientation = Owner.Orientation
}
/** /**
* na * Override for a `Terminal` object so that it inherits the spatial characteristics of its `Owner`.
* The `Terminal` `Utility` produced has proximity effects.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
class ProximityTerminalUtility(tdef : TerminalDefinition) extends Terminal(tdef)
with UtilityWorldEntity
with ProximityUnit
/**
* Override for a `Terminal` object so that it inherits the spatial characteristics of its `Owner`.
* The `Terminal` `Utility` produced dispenses a specific item
* that retain knowledge of the `Owner` of the `Terminal` that dispensed it.
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields * @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/ */
class TeleportPadTerminalUtility(tdef : TerminalDefinition) extends TerminalUtility(tdef) { class TeleportPadTerminalUtility(tdef : TerminalDefinition) extends TerminalUtility(tdef) {
@ -192,7 +220,7 @@ object Utility {
case UtilityType.bfr_rearm_terminal => case UtilityType.bfr_rearm_terminal =>
_OrderTerminalDefinition.Setup _OrderTerminalDefinition.Setup
case UtilityType.lodestar_repair_terminal => case UtilityType.lodestar_repair_terminal =>
OrderTerminalABDefinition.Setup //TODO wrong ProximityTerminal.Setup
case UtilityType.matrix_terminalc => case UtilityType.matrix_terminalc =>
MatrixTerminalDefinition.Setup MatrixTerminalDefinition.Setup
case UtilityType.multivehicle_rearm_terminal => case UtilityType.multivehicle_rearm_terminal =>

View file

@ -13,12 +13,15 @@ import net.psforever.objects.guid.actor.UniqueNumberSystem
import net.psforever.objects.guid.selector.RandomSelector import net.psforever.objects.guid.selector.RandomSelector
import net.psforever.objects.guid.source.LimitedNumberSource import net.psforever.objects.guid.source.LimitedNumberSource
import net.psforever.objects.inventory.Container import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.structures.{Amenity, Building}
import net.psforever.objects.serverobject.terminals.ProximityUnit
import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.serverobject.tube.SpawnTube
import net.psforever.objects.serverobject.turret.FacilityTurret import net.psforever.objects.serverobject.turret.FacilityTurret
import net.psforever.packet.game.PlanetSideGUID import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.Vector3 import net.psforever.types.Vector3
import services.Service
import scala.collection.concurrent.TrieMap import scala.collection.concurrent.TrieMap
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
@ -366,6 +369,13 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
case silo : ResourceSilo => case silo : ResourceSilo =>
silo.Actor ! "startup" silo.Actor ! "startup"
} }
//proximity terminals need to startup
buildings.values
.flatMap(_.Amenities.filter(_.isInstanceOf[ProximityUnit]))
.collect {
case o : PlanetSideServerObject =>
o.Actor ! Service.Startup()
}
} }
private def CreateSpawnGroups() : Unit = { private def CreateSpawnGroups() : Unit = {

View file

@ -0,0 +1,16 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.zones
/**
* The object must be able to recall on which of the defined game worlds (zones) that it exists on command.
* The game world identifier string produced should be equivalent to a `Zone.Id` string for some equivalent `Zone` object.
* The identifier "nowhere" is recommended as the default invalid location.
* @see `InterstellarCluster`
* @see `WorldEntity`
* @see `Zone`
*/
trait ZoneAware {
def Continent : String
def Continent_=(zone : String) : String
}

View file

@ -46,11 +46,49 @@ final case class Vector3(x : Float,
* @return a new `Vector3` object with only two of the components of the original * @return a new `Vector3` object with only two of the components of the original
*/ */
def xy : Vector3 = Vector3(x, y, 0) def xy : Vector3 = Vector3(x, y, 0)
/**
* Perform the x-axis rotation of this `Vector3` element where the angle of rotation is assumed in degrees.
* For chaining rotations.
* @see `Vector3.Rx`
* @param ang a rotation angle
* @return the rotated vector
*/
def Rx(ang : Float) : Vector3 = Vector3.Rx(this, ang)
/**
* Perform the y-axis rotation of this `Vector3` element where the angle of rotation is assumed in degrees.
* For chaining rotations.
* @see `Vector3.Ry`
* @param ang a rotation angle
* @return the rotated vector
*/
def Ry(ang : Float) : Vector3 = Vector3.Ry(this, ang)
/**
* Perform the z-axis rotation of this `Vector3` element where the angle of rotation is assumed in degrees.
* For chaining rotations.
* @see `Vector3.Rz`
* @param ang a rotation angle
* @return the rotated vector
*/
def Rz(ang : Float) : Vector3 = Vector3.Rz(this, ang)
} }
object Vector3 { object Vector3 {
final val Zero : Vector3 = Vector3(0f, 0f, 0f) final val Zero : Vector3 = Vector3(0f, 0f, 0f)
private def closeToInsignificance(d : Float, epsilon : Float = 10f) : Float = {
val ulp = math.ulp(epsilon)
math.signum(d) match {
case -1f =>
val n = math.abs(d)
val p = math.abs(n - n.toInt)
if(p < ulp || d > ulp) d + p else d
case _ =>
val p = math.abs(d - d.toInt)
if(p < ulp || d < ulp) d - p else d
}
}
implicit val codec_pos : Codec[Vector3] = ( implicit val codec_pos : Codec[Vector3] = (
("x" | newcodecs.q_float(0.0, 8192.0, 20)) :: ("x" | newcodecs.q_float(0.0, 8192.0, 20)) ::
("y" | newcodecs.q_float(0.0, 8192.0, 20)) :: ("y" | newcodecs.q_float(0.0, 8192.0, 20)) ::
@ -208,4 +246,82 @@ object Vector3 {
def VectorProjection(vec1 : Vector3, vec2 : Vector3) : Vector3 = { def VectorProjection(vec1 : Vector3, vec2 : Vector3) : Vector3 = {
Unit(vec2) * ScalarProjection(vec1, vec2) Unit(vec2) * ScalarProjection(vec1, vec2)
} }
/**
* Perform the x-axis rotation of a `Vector3` element where the angle of rotation is assumed in degrees.
* @see `Vector3.RxRadians(Vector3, Double)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in degrees
* @return the rotated vector
*/
def Rx(vec : Vector3, ang : Float) : Vector3 = Rx(vec, math.toRadians(ang))
/**
* Perform the x-axis rotation of a `Vector3` element where the angle of rotation is assumed in radians.
* @see `Vector3.Rx(Vector3, Float)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in radians
* @return the rotated vector
*/
def Rx(vec : Vector3, ang : Double) : Vector3 = {
val cos = math.cos(ang).toFloat
val sin = math.sin(ang).toFloat
val (x, y, z) = (vec.x, vec.y, vec.z)
Vector3(
x,
closeToInsignificance(y * cos - z * sin),
closeToInsignificance(y * sin + z * cos)
)
}
/**
* Perform the x-axis rotation of a `Vector3` element where the angle of rotation is assumed in degrees.
* @see `Vector3.Ry(Vector3, Double)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in degrees
* @return the rotated vector
*/
def Ry(vec : Vector3, ang : Float) : Vector3 = Ry(vec, math.toRadians(ang))
/**
* Perform the y-axis rotation of a `Vector3` element where the angle of rotation is assumed in radians.
* @see `Vector3.Ry(Vector3, Float)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in radians
* @return the rotated vector
*/
def Ry(vec : Vector3, ang : Double) : Vector3 = {
val cos = math.cos(ang).toFloat
val sin = math.sin(ang).toFloat
val (x, y, z) = (vec.x, vec.y, vec.z)
Vector3(
closeToInsignificance(x * cos + z * sin),
y,
closeToInsignificance(z * cos - x * sin)
)
}
/**
* Perform the x-axis rotation of a `Vector3` element where the angle of rotation is assumed in degrees.
* @see `Vector3.Rz(Vector3, Double)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in degrees
* @return the rotated vector
*/
def Rz(vec : Vector3, ang : Float) : Vector3 = Rz(vec, math.toRadians(ang))
/**
* Perform the z-axis rotation of a `Vector3` element where the angle of rotation is assumed in radians.
* @see `Vector3.Rz(Vector3, Float)`
* @param vec a mathematical vector representing direction
* @param ang a rotation angle, in radians
* @return the rotation vector
*/
def Rz(vec : Vector3, ang : Double) : Vector3 = {
val cos = math.cos(ang).toFloat
val sin = math.sin(ang).toFloat
val (x, y, z) = (vec.x, vec.y, vec.z)
Vector3(
closeToInsignificance(x * cos - y * sin),
closeToInsignificance(x * sin - y * cos),
z
)
}
} }

View file

@ -23,7 +23,6 @@ object LocalAction {
final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, duration: Int, unk2 : Long = 8L) extends Action final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, duration: Int, unk2 : Long = 8L) extends Action
final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) extends Action final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) extends Action
final case class HackCaptureTerminal(player_guid : PlanetSideGUID, continent : Zone, target : CaptureTerminal, unk1 : Long, unk2 : Long = 8L, isResecured : Boolean) extends Action final case class HackCaptureTerminal(player_guid : PlanetSideGUID, continent : Zone, target : CaptureTerminal, unk1 : Long, unk2 : Long = 8L, isResecured : Boolean) extends Action
final case class ProximityTerminalEffect(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, effectState : Boolean) extends Action
final case class RouterTelepadTransport(player_guid : PlanetSideGUID, passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Action final case class RouterTelepadTransport(player_guid : PlanetSideGUID, passenger_guid : PlanetSideGUID, src_guid : PlanetSideGUID, dest_guid : PlanetSideGUID) extends Action
final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Action final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Action
final case class ToggleTeleportSystem(player_guid : PlanetSideGUID, router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Action final case class ToggleTeleportSystem(player_guid : PlanetSideGUID, router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Action

View file

@ -5,7 +5,7 @@ import akka.actor.{Actor, ActorRef, Props}
import net.psforever.objects.ce.Deployable import net.psforever.objects.ce.Deployable
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.serverobject.terminals.CaptureTerminal import net.psforever.objects.serverobject.terminals.{CaptureTerminal, ProximityUnit, Terminal}
import net.psforever.objects.zones.{InterstellarCluster, Zone} import net.psforever.objects.zones.{InterstellarCluster, Zone}
import net.psforever.objects._ import net.psforever.objects._
import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation} import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation}
@ -111,10 +111,6 @@ class LocalService extends Actor {
LocalEvents.publish( LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackCaptureTerminal(target.GUID, unk1, unk2, isResecured)) LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackCaptureTerminal(target.GUID, unk1, unk2, isResecured))
) )
case LocalAction.ProximityTerminalEffect(player_guid, object_guid, effectState) =>
LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.ProximityTerminalEffect(object_guid, effectState))
)
case LocalAction.RouterTelepadTransport(player_guid, passenger_guid, src_guid, dest_guid) => case LocalAction.RouterTelepadTransport(player_guid, passenger_guid, src_guid, dest_guid) =>
LocalEvents.publish( LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.RouterTelepadTransport(passenger_guid, src_guid, dest_guid)) LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.RouterTelepadTransport(passenger_guid, src_guid, dest_guid))
@ -159,6 +155,16 @@ class LocalService extends Actor {
LocalServiceResponse(s"/$zone_id/Local", Service.defaultPlayerGUID, LocalResponse.HackClear(target_guid, unk1, unk2)) LocalServiceResponse(s"/$zone_id/Local", Service.defaultPlayerGUID, LocalResponse.HackClear(target_guid, unk1, unk2))
) )
//message from ProximityTerminalControl
case Terminal.StartProximityEffect(terminal) =>
LocalEvents.publish(
LocalServiceResponse(s"/${terminal.Owner.Continent}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, true))
)
case Terminal.StopProximityEffect(terminal) =>
LocalEvents.publish(
LocalServiceResponse(s"/${terminal.Owner.Continent}/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(terminal.GUID, false))
)
case HackCaptureActor.HackTimeoutReached(capture_terminal_guid, zone_id, _, _, hackedByFaction) => case HackCaptureActor.HackTimeoutReached(capture_terminal_guid, zone_id, _, _, hackedByFaction) =>
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
ask(cluster, InterstellarCluster.GetWorld(zone_id))(1 seconds).onComplete { ask(cluster, InterstellarCluster.GetWorld(zone_id))(1 seconds).onComplete {

View file

@ -2,9 +2,13 @@
package services.vehicle package services.vehicle
import akka.actor.{Actor, ActorRef, Props} import akka.actor.{Actor, ActorRef, Props}
import net.psforever.objects.Vehicle
import net.psforever.objects.ballistics.VehicleSource
import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.serverobject.pad.VehicleSpawnPad
import net.psforever.objects.serverobject.terminals.{MedicalTerminalDefinition, ProximityUnit}
import net.psforever.objects.vital.RepairFromTerm
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.{ObjectCreateMessage, PlanetSideGUID}
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
import services.vehicle.support.{TurretUpgrader, VehicleRemover} import services.vehicle.support.{TurretUpgrader, VehicleRemover}
import net.psforever.types.DriveState import net.psforever.types.DriveState
@ -189,6 +193,18 @@ class VehicleService extends Actor {
VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.UpdateAmsSpawnPoint(AmsSpawnPoints(zone))) VehicleServiceResponse(s"/${zone.Id}/Vehicle", Service.defaultPlayerGUID, VehicleResponse.UpdateAmsSpawnPoint(AmsSpawnPoints(zone)))
) )
//from ProximityTerminalControl (?)
case ProximityUnit.Action(term, target : Vehicle) =>
val medDef = term.Definition.asInstanceOf[MedicalTerminalDefinition]
val healAmount = medDef.HealAmount
if(healAmount != 0 && term.Validate(target) && target.Health < target.MaxHealth) {
target.Health = target.Health + healAmount
target.History(RepairFromTerm(VehicleSource(target), healAmount, medDef))
VehicleEvents.publish(
VehicleServiceResponse(s"/${term.Continent}/Vehicle", PlanetSideGUID(0), VehicleResponse.PlanetsideAttribute(target.GUID, 0, target.Health))
)
}
case msg => case msg =>
log.info(s"Unhandled message $msg from $sender") log.info(s"Unhandled message $msg from $sender")
} }

View file

@ -201,5 +201,44 @@ class Vector3Test extends Specification {
Vector3.VectorProjection(A, B) mustEqual Vector3(1.0384614f, 1.3846153f, 0.34615383f) Vector3.VectorProjection(A, B) mustEqual Vector3(1.0384614f, 1.3846153f, 0.34615383f)
Vector3.VectorProjection(B, A) mustEqual Vector3(2.9999998f, 1.4999999f, -1.4999999f) Vector3.VectorProjection(B, A) mustEqual Vector3(2.9999998f, 1.4999999f, -1.4999999f)
} }
"rotate positive x-axis-vector 90-degrees around the z-axis" in {
val A : Vector3 = Vector3(1, 0, 0)
A.Rz(0) mustEqual A
A.Rz(90) mustEqual Vector3(0, 1, 0)
A.Rz(180) mustEqual Vector3(-1, 0, 0)
A.Rz(270) mustEqual Vector3(0, -1, 0)
A.Rz(360) mustEqual A
}
"rotate positive y-axis-vector 90-degrees around the x-axis" in {
val A : Vector3 = Vector3(0, 1, 0)
A.Rx(0) mustEqual A
A.Rx(90) mustEqual Vector3(0, 0, 1)
A.Rx(180) mustEqual Vector3(0, -1, 0)
A.Rx(270) mustEqual Vector3(0, 0, -1)
A.Rx(360) mustEqual A
}
"rotate positive x-axis-vector 90-degrees around the y-axis" in {
val A : Vector3 = Vector3(1, 0, 0)
A.Ry(0) mustEqual A
A.Ry(90) mustEqual Vector3(0, 0, -1)
A.Ry(180) mustEqual Vector3(-1, 0, 0)
A.Ry(270) mustEqual Vector3(0, 0, 1)
A.Ry(360) mustEqual A
}
"compound rotation" in {
val A : Vector3 = Vector3(1, 0, 0)
A.Rz(90)
.Rx(90)
.Ry(90) mustEqual A
}
"45-degree rotation" in {
val A : Vector3 = Vector3(1, 0, 0)
A.Rz(45) mustEqual Vector3(0.70710677f, 0.70710677f, 0)
}
} }
} }

View file

@ -1,90 +0,0 @@
// Copyright (c) 2017 PSForever
package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.terminals.{MedicalTerminalDefinition, ProximityTerminal, Terminal}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
import org.specs2.mutable.Specification
class MedicalTerminalTest extends Specification {
"MedicalTerminal" should {
"define (a)" in {
val a = new MedicalTerminalDefinition(38)
a.ObjectId mustEqual 38
a.Name mustEqual "adv_med_terminal"
}
"define (b)" in {
val b = new MedicalTerminalDefinition(225)
b.ObjectId mustEqual 225
b.Name mustEqual "crystals_health_a"
}
"define (c)" in {
val c = new MedicalTerminalDefinition(226)
c.ObjectId mustEqual 226
c.Name mustEqual "crystals_health_b"
}
"define (d)" in {
val d = new MedicalTerminalDefinition(529)
d.ObjectId mustEqual 529
d.Name mustEqual "medical_terminal"
}
"define (e)" in {
val e = new MedicalTerminalDefinition(689)
e.ObjectId mustEqual 689
e.Name mustEqual "portable_med_terminal"
}
"define (invalid)" in {
var id : Int = (math.random * Int.MaxValue).toInt
if(id == 224) {
id += 2
}
else if(id == 37) {
id += 1
}
else if(id == 528) {
id += 1
}
else if(id == 688) {
id += 1
}
new MedicalTerminalDefinition(id) must throwA[IllegalArgumentException]
}
}
"Medical_Terminal" should {
"construct" in {
ProximityTerminal(GlobalDefinitions.medical_terminal).Actor mustEqual ActorRef.noSender
}
"can add a player to a list of users" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.NumberUsers mustEqual 0
terminal.AddUser(PlanetSideGUID(10))
terminal.NumberUsers mustEqual 1
}
"can remove a player from a list of users" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.AddUser(PlanetSideGUID(10))
terminal.NumberUsers mustEqual 1
terminal.RemoveUser(PlanetSideGUID(10))
terminal.NumberUsers mustEqual 0
}
"player can not interact with the proximity terminal normally (buy)" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
}
}
}

View file

@ -1,120 +0,0 @@
// Copyright (c) 2017 PSForever
package objects.terminal
import akka.actor.{ActorSystem, Props}
import base.ActorTest
import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals._
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
import scala.concurrent.duration.Duration
class ProximityTerminalControl1Test extends ActorTest {
"ProximityTerminalControl" should {
"construct (medical terminal)" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-term")
}
}
}
class ProximityTerminalControl2Test extends ActorTest {
"ProximityTerminalControl can not process wrong messages" in {
val (_, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
terminal.Actor !"hello"
expectNoMsg(Duration.create(500, "ms"))
}
}
//terminal control is mostly a pass-through actor for Terminal.Exchange messages, wrapped in Terminal.TerminalMessage protocol
class MedicalTerminalControl1Test extends ActorTest {
"ProximityTerminalControl sends a message to the first new user only" in {
val (player, terminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
val reply = receiveOne(Duration.create(500, "ms"))
assert(reply.isInstanceOf[Terminal.TerminalMessage])
val reply2 = reply.asInstanceOf[Terminal.TerminalMessage]
assert(reply2.player == player)
assert(reply2.msg == null)
assert(reply2.response.isInstanceOf[Terminal.StartProximityEffect])
assert(reply2.response.asInstanceOf[Terminal.StartProximityEffect].terminal == terminal)
assert(terminal.NumberUsers == 1)
terminal.Actor ! CommonMessages.Use(player2)
expectNoMsg(Duration.create(500, "ms"))
assert(terminal.NumberUsers == 2)
}
}
class MedicalTerminalControl2Test extends ActorTest {
"ProximityTerminalControl sends a message to the last user only" in {
val (player, terminal) : (Player, ProximityTerminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
receiveOne(Duration.create(500, "ms"))
terminal.Actor ! CommonMessages.Use(player2)
expectNoMsg(Duration.create(500, "ms"))
assert(terminal.NumberUsers == 2)
terminal.Actor ! CommonMessages.Unuse(player)
expectNoMsg(Duration.create(500, "ms"))
assert(terminal.NumberUsers == 1)
terminal.Actor ! CommonMessages.Unuse(player2)
val reply = receiveOne(Duration.create(500, "ms"))
assert(reply.isInstanceOf[Terminal.TerminalMessage])
val reply2 = reply.asInstanceOf[Terminal.TerminalMessage]
assert(reply2.player == player2)
assert(reply2.msg == null)
assert(reply2.response.isInstanceOf[Terminal.StopProximityEffect])
assert(reply2.response.asInstanceOf[Terminal.StopProximityEffect].terminal == terminal)
assert(terminal.NumberUsers == 0)
}
}
class MedicalTerminalControl3Test extends ActorTest {
"ProximityTerminalControl sends a message to the last user only (confirmation of test #2)" in {
val (player, terminal) : (Player, ProximityTerminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
receiveOne(Duration.create(500, "ms"))
terminal.Actor ! CommonMessages.Use(player2)
expectNoMsg(Duration.create(500, "ms"))
assert(terminal.NumberUsers == 2)
terminal.Actor ! CommonMessages.Unuse(player2)
expectNoMsg(Duration.create(500, "ms"))
assert(terminal.NumberUsers == 1)
terminal.Actor ! CommonMessages.Unuse(player)
val reply = receiveOne(Duration.create(500, "ms"))
assert(reply.isInstanceOf[Terminal.TerminalMessage])
val reply2 = reply.asInstanceOf[Terminal.TerminalMessage]
assert(reply2.player == player) //important!
assert(reply2.msg == null)
assert(reply2.response.isInstanceOf[Terminal.StopProximityEffect])
assert(reply2.response.asInstanceOf[Terminal.StopProximityEffect].terminal == terminal)
assert(terminal.NumberUsers == 0)
}
}
object ProximityTerminalControlTest {
def SetUpAgents(tdef : MedicalTerminalDefinition, faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, ProximityTerminal) = {
val terminal = ProximityTerminal(tdef)
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-term")
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), terminal)
}
}

View file

@ -2,14 +2,19 @@
package objects.terminal package objects.terminal
import akka.actor.Props import akka.actor.Props
import akka.testkit.TestProbe
import base.ActorTest import base.ActorTest
import net.psforever.objects.guid.TaskResolver
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.terminals.Terminal.TerminalMessage import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, ProximityTerminalControl, ProximityUnit, Terminal} import net.psforever.objects.serverobject.terminals.{ProximityTerminal, ProximityTerminalControl, ProximityUnit, Terminal}
import net.psforever.objects.zones.{Zone, ZoneActor, ZoneMap}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player} import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.PlanetSideGUID import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire} import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
import org.specs2.mutable.Specification import org.specs2.mutable.Specification
import services.{Service, ServiceManager}
import services.local.{LocalResponse, LocalService, LocalServiceResponse}
import scala.concurrent.duration._ import scala.concurrent.duration._
@ -21,39 +26,62 @@ class ProximityTest extends Specification {
} }
"keep track of users (add)" in { "keep track of users (add)" in {
val obj = new ProximityTest.SampleTerminal() val avatar1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar1.Spawn
avatar1.Health = 50
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar2.Spawn
avatar2.Health = 50
val obj = new ProximityTerminal(GlobalDefinitions.medical_terminal)
obj.NumberUsers mustEqual 0 obj.NumberUsers mustEqual 0
obj.AddUser(PlanetSideGUID(10)) mustEqual obj.NumberUsers obj.AddUser(avatar1) mustEqual true
obj.NumberUsers mustEqual 1 obj.NumberUsers mustEqual 1
obj.AddUser(PlanetSideGUID(20)) mustEqual obj.NumberUsers obj.AddUser(avatar2) mustEqual true
obj.NumberUsers mustEqual 2 obj.NumberUsers mustEqual 2
} }
"keep track of users (remove)" in { "keep track of users (remove)" in {
val obj = new ProximityTest.SampleTerminal() val avatar1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
obj.AddUser(PlanetSideGUID(10)) avatar1.Spawn
obj.AddUser(PlanetSideGUID(20)) avatar1.Health = 50
obj.NumberUsers mustEqual 2 val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
obj.RemoveUser(PlanetSideGUID(10)) mustEqual obj.NumberUsers avatar2.Spawn
avatar2.Health = 50
val obj = new ProximityTerminal(GlobalDefinitions.medical_terminal)
obj.NumberUsers mustEqual 0
obj.AddUser(avatar1) mustEqual true
obj.NumberUsers mustEqual 1 obj.NumberUsers mustEqual 1
obj.RemoveUser(PlanetSideGUID(20)) mustEqual obj.NumberUsers obj.AddUser(avatar2) mustEqual true
obj.NumberUsers mustEqual 2
obj.RemoveUser(avatar1) mustEqual true
obj.NumberUsers mustEqual 1
obj.RemoveUser(avatar2) mustEqual true
obj.NumberUsers mustEqual 0 obj.NumberUsers mustEqual 0
} }
"can not add a user twice" in { "can not add a user twice" in {
val obj = new ProximityTest.SampleTerminal() val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
obj.AddUser(PlanetSideGUID(10)) avatar.Spawn
avatar.Health = 50
val obj = new ProximityTerminal(GlobalDefinitions.medical_terminal)
obj.AddUser(avatar) mustEqual true
obj.NumberUsers mustEqual 1 obj.NumberUsers mustEqual 1
obj.AddUser(PlanetSideGUID(10)) obj.AddUser(avatar)// mustEqual false
obj.NumberUsers mustEqual 1 obj.NumberUsers mustEqual 1
} }
"can not remove a user that was not added" in { "can not remove a user that was not added" in {
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar.Spawn
avatar.Health = 50
val obj = new ProximityTest.SampleTerminal() val obj = new ProximityTest.SampleTerminal()
obj.AddUser(PlanetSideGUID(10)) obj.RemoveUser(avatar) mustEqual false
obj.NumberUsers mustEqual 1 obj.NumberUsers mustEqual 0
obj.RemoveUser(PlanetSideGUID(20))
obj.NumberUsers mustEqual 1
} }
} }
@ -65,106 +93,216 @@ class ProximityTest extends Specification {
} }
} }
class ProximityTerminalControl1bTest extends ActorTest { class ProximityTerminalControlStartTest extends ActorTest {
"ProximityTerminalControl" should { "ProximityTerminalControl" should {
//setup
val probe = new TestProbe(system)
val service = ServiceManager.boot(system)
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
override def SetupNumberPools() = {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar.Continent = "test"
avatar.Spawn
avatar.Health = 50
avatar.GUID = PlanetSideGUID(1)
terminal.GUID = PlanetSideGUID(2)
terminal.Actor ! Service.Startup()
expectNoMsg(500 milliseconds) //spacer
"send out a start message" in { "send out a start message" in {
val obj = ProximityTerminal(GlobalDefinitions.medical_terminal) assert(terminal.NumberUsers == 0)
obj.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], obj), "prox-ctrl") assert(terminal.Owner.Continent.equals("test"))
val player = Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
player.GUID = PlanetSideGUID(10)
assert(obj.NumberUsers == 0) val msg = probe.receiveOne(500 milliseconds)
obj.Actor ! CommonMessages.Use(player) assert(terminal.NumberUsers == 1)
val msg = receiveOne(200 milliseconds) assert(msg.isInstanceOf[LocalServiceResponse])
assert(obj.NumberUsers == 1) val resp = msg.asInstanceOf[LocalServiceResponse]
assert(msg.isInstanceOf[TerminalMessage]) assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
val msgout = msg.asInstanceOf[TerminalMessage]
assert(msgout.player == player)
assert(msgout.msg == null)
assert(msgout.response.isInstanceOf[Terminal.StartProximityEffect])
} }
} }
} }
class ProximityTerminalControl2bTest extends ActorTest { class ProximityTerminalControlTwoUsersTest extends ActorTest {
"ProximityTerminalControl" should { "ProximityTerminalControl" should {
"will not send out one start message unless first user" in { //setup
val obj = ProximityTerminal(GlobalDefinitions.medical_terminal) val probe = new TestProbe(system)
obj.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], obj), "prox-ctrl") val service = ServiceManager.boot(system)
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
player1.GUID = PlanetSideGUID(10) service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) service ! ServiceManager.Register(Props[TaskResolver], "cluster")
player2.GUID = PlanetSideGUID(11) val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
assert(obj.NumberUsers == 0) terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
override def SetupNumberPools() = {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar.Continent = "test"
avatar.Spawn
avatar.Health = 50
obj.Actor ! CommonMessages.Use(player1) avatar.GUID = PlanetSideGUID(1)
val msg = receiveOne(200 milliseconds) terminal.GUID = PlanetSideGUID(2)
assert(obj.NumberUsers == 1) terminal.Actor ! Service.Startup()
assert(msg.isInstanceOf[TerminalMessage]) expectNoMsg(500 milliseconds) //spacer
assert(msg.asInstanceOf[TerminalMessage].response.isInstanceOf[Terminal.StartProximityEffect])
obj.Actor ! CommonMessages.Use(player2) "will not send out a start message if not the first user" in {
expectNoMsg(500 milliseconds) assert(terminal.NumberUsers == 0)
assert(obj.NumberUsers == 2) assert(terminal.Owner.Continent.equals("test"))
terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
val msg = probe.receiveOne(500 milliseconds)
assert(terminal.NumberUsers == 1)
assert(msg.isInstanceOf[LocalServiceResponse])
val resp = msg.asInstanceOf[LocalServiceResponse]
assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar2.Continent = "test"
avatar2.Spawn
avatar2.Health = 50
terminal.Actor ! CommonMessages.Use(avatar2, Some(avatar2))
probe.expectNoMsg(500 milliseconds)
assert(terminal.NumberUsers == 2)
} }
} }
} }
class ProximityTerminalControl3bTest extends ActorTest { class ProximityTerminalControlStopTest extends ActorTest {
"ProximityTerminalControl" should { "ProximityTerminalControl" should {
//setup
val probe = new TestProbe(system)
val service = ServiceManager.boot(system)
service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
service ! ServiceManager.Register(Props[TaskResolver], "cluster")
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
override def SetupNumberPools() = {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar.Continent = "test"
avatar.Spawn
avatar.Health = 50
avatar.GUID = PlanetSideGUID(1)
terminal.GUID = PlanetSideGUID(2)
terminal.Actor ! Service.Startup()
expectNoMsg(500 milliseconds) //spacer
"send out a stop message" in { "send out a stop message" in {
val obj = ProximityTerminal(GlobalDefinitions.medical_terminal) assert(terminal.NumberUsers == 0)
obj.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], obj), "prox-ctrl") assert(terminal.Owner.Continent.equals("test"))
val player = Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.GUID = PlanetSideGUID(10)
assert(obj.NumberUsers == 0) terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
obj.Actor ! CommonMessages.Use(player) val msg1 = probe.receiveOne(500 milliseconds)
receiveOne(200 milliseconds) assert(terminal.NumberUsers == 1)
assert(obj.NumberUsers == 1) assert(msg1.isInstanceOf[LocalServiceResponse])
obj.Actor ! CommonMessages.Unuse(player) val resp1 = msg1.asInstanceOf[LocalServiceResponse]
val msg = receiveOne(200 milliseconds) assert(resp1.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
assert(obj.NumberUsers == 0)
assert(msg.isInstanceOf[TerminalMessage]) terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
val msgout = msg.asInstanceOf[TerminalMessage] val msg2 = probe.receiveWhile(500 milliseconds) {
assert(msgout.player == player) case LocalServiceResponse(_, _, replyMessage) => replyMessage
assert(msgout.msg == null) }
assert(msgout.response.isInstanceOf[Terminal.StopProximityEffect]) assert(terminal.NumberUsers == 0)
assert(msg2.last == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), false))
} }
} }
} }
class ProximityTerminalControl4bTest extends ActorTest { class ProximityTerminalControlNotStopTest extends ActorTest {
"ProximityTerminalControl" should { "ProximityTerminalControl" should {
"will not send out one stop message until last user" in { //setup
val obj = ProximityTerminal(GlobalDefinitions.medical_terminal) val probe = new TestProbe(system)
obj.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], obj), "prox-ctrl") val service = ServiceManager.boot(system)
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) service ! ServiceManager.Register(Props(classOf[ProximityTest.ProbedLocalService], probe), "local")
player1.GUID = PlanetSideGUID(10) service ! ServiceManager.Register(Props[TaskResolver], "taskResolver")
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) service ! ServiceManager.Register(Props[TaskResolver], "cluster")
player2.GUID = PlanetSideGUID(11) val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
assert(obj.NumberUsers == 0) terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-prox")
val zone : Zone = new Zone("test", new ZoneMap("test-map"), 0) {
Actor = system.actorOf(Props(classOf[ZoneActor], this), "test-zone")
override def SetupNumberPools() = {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
val avatar = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar.Continent = "test"
avatar.Spawn
avatar.Health = 50
obj.Actor ! CommonMessages.Use(player1) avatar.GUID = PlanetSideGUID(1)
receiveOne(200 milliseconds) //StartProximityEffect terminal.GUID = PlanetSideGUID(2)
assert(obj.NumberUsers == 1) terminal.Actor ! Service.Startup()
obj.Actor ! CommonMessages.Use(player2) expectNoMsg(500 milliseconds) //spacer
expectNoMsg(500 milliseconds)
assert(obj.NumberUsers == 2) "will not send out one stop message until last user" in {
obj.Actor ! CommonMessages.Unuse(player1) assert(terminal.NumberUsers == 0)
expectNoMsg(500 milliseconds) assert(terminal.Owner.Continent.equals("test"))
assert(obj.NumberUsers == 1)
obj.Actor ! CommonMessages.Unuse(player2) terminal.Actor ! CommonMessages.Use(avatar, Some(avatar))
val msg = receiveOne(200 milliseconds) val msg = probe.receiveOne(500 milliseconds)
assert(obj.NumberUsers == 0) assert(terminal.NumberUsers == 1)
assert(msg.isInstanceOf[TerminalMessage]) assert(msg.isInstanceOf[LocalServiceResponse])
val msgout = msg.asInstanceOf[TerminalMessage] val resp = msg.asInstanceOf[LocalServiceResponse]
assert(msgout.player == player2) assert(resp.replyMessage == LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), true))
assert(msgout.msg == null)
assert(msgout.response.isInstanceOf[Terminal.StopProximityEffect]) val avatar2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
avatar2.Continent = "test"
avatar2.Spawn
avatar2.Health = 50
terminal.Actor ! CommonMessages.Use(avatar2, Some(avatar2))
probe.expectNoMsg(500 milliseconds)
assert(terminal.NumberUsers == 2)
terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
val msg2 = probe.receiveWhile(500 milliseconds) {
case LocalServiceResponse(_, _, replyMessage) => replyMessage
}
assert(terminal.NumberUsers == 1)
assert(!msg2.contains(LocalResponse.ProximityTerminalEffect(PlanetSideGUID(2), false)))
} }
} }
} }
object ProximityTest { object ProximityTest {
class SampleTerminal extends Terminal(GlobalDefinitions.dropship_vehicle_terminal) with ProximityUnit class SampleTerminal extends Terminal(GlobalDefinitions.dropship_vehicle_terminal) with ProximityUnit
class ProbedLocalService(probe : TestProbe) extends LocalService {
self.tell(Service.Join("test"), probe.ref)
}
} }

View file

@ -1,91 +0,0 @@
// Copyright (c) 2017 PSForever
package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects._
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
import org.specs2.mutable.Specification
class RepairRearmSiloTest extends Specification {
"RepairRearmSilo" should {
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
val silo = Terminal(GlobalDefinitions.repair_silo)
silo.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
silo.Owner.Faction = PlanetSideEmpire.TR
"define" in {
GlobalDefinitions.repair_silo.ObjectId mustEqual 729
}
"construct" in {
val obj = Terminal(GlobalDefinitions.repair_silo)
obj.Actor mustEqual ActorRef.noSender
}
"player can buy a box of ammunition ('bullet_35mm')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 3, "35mmbullet", 0, PlanetSideGUID(0))
val reply = silo.Request(player, msg)
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
val reply2 = reply.asInstanceOf[Terminal.BuyEquipment]
reply2.item.isInstanceOf[AmmoBox] mustEqual true
reply2.item.asInstanceOf[AmmoBox].Definition mustEqual GlobalDefinitions.bullet_35mm
reply2.item.asInstanceOf[AmmoBox].Capacity mustEqual 100
}
"player can not buy fake equipment ('sabot')" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 3, "sabot", 0, PlanetSideGUID(0))
silo.Request(player, msg) mustEqual Terminal.NoDeal()
}
"player can not buy equipment from the wrong page ('35mmbullet', page 1)" in {
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "35mmbullet", 0, PlanetSideGUID(0))
silo.Request(player, msg) mustEqual Terminal.NoDeal()
}
"player can retrieve a vehicle loadout" in {
val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
val player2 = Player(avatar)
val vehicle = Vehicle(GlobalDefinitions.fury)
vehicle.Slot(30).Equipment = AmmoBox(GlobalDefinitions.bullet_9mm)
avatar.SaveLoadout(vehicle, "test", 10)
val msg = silo.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 0, PlanetSideGUID(0)))
msg.isInstanceOf[Terminal.VehicleLoadout] mustEqual true
val loadout = msg.asInstanceOf[Terminal.VehicleLoadout]
loadout.vehicle_definition mustEqual GlobalDefinitions.fury
loadout.weapons.size mustEqual 1
loadout.weapons.head.obj.Definition mustEqual GlobalDefinitions.fury_weapon_systema
loadout.weapons.head.start mustEqual 1
loadout.inventory.head.obj.Definition mustEqual GlobalDefinitions.bullet_9mm
loadout.inventory.head.start mustEqual 30
}
"player can not retrieve a vehicle loadout from the wrong line" in {
val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
val player2 = Player(avatar)
val vehicle = Vehicle(GlobalDefinitions.fury)
vehicle.Slot(30).Equipment = AmmoBox(GlobalDefinitions.bullet_9mm)
avatar.SaveLoadout(vehicle, "test", 10)
val msg = silo.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 3, "", 0, PlanetSideGUID(0))) //page 3
msg.isInstanceOf[Terminal.NoDeal] mustEqual true
}
"player can not retrieve a vehicle loadout from the wrong line" in {
val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
val player2 = Player(avatar)
val vehicle = Vehicle(GlobalDefinitions.fury)
vehicle.Slot(30).Equipment = AmmoBox(GlobalDefinitions.bullet_9mm)
avatar.SaveLoadout(vehicle, "test", 10)
val msg = silo.Request(player2, ItemTransactionMessage(PlanetSideGUID(10), TransactionType.Loadout, 4, "", 1, PlanetSideGUID(0))) //line 11
msg.isInstanceOf[Terminal.NoDeal] mustEqual true
}
}
}

View file

@ -5,6 +5,7 @@ import akka.actor.Props
import base.ActorTest import base.ActorTest
import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle} import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
import net.psforever.packet.game._ import net.psforever.packet.game._
import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.types.{PlanetSideEmpire, Vector3}
import services.{Service, ServiceManager} import services.{Service, ServiceManager}
@ -141,15 +142,32 @@ class HackClearTest extends ActorTest {
} }
} }
class ProximityTerminalEffectTest extends ActorTest { class ProximityTerminalEffectOnTest extends ActorTest {
ServiceManager.boot(system) ServiceManager.boot(system)
val service = system.actorOf(Props[LocalService], "l_service")
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.GUID = PlanetSideGUID(1)
"LocalService" should { "LocalService" should {
"pass ProximityTerminalEffect" in { "pass ProximityTerminalEffect (true)" in {
val service = system.actorOf(Props[LocalService], "l_service") service ! Service.Join("nowhere")
service ! Service.Join("test") service ! Terminal.StartProximityEffect(terminal)
service ! LocalServiceMessage("test", LocalAction.ProximityTerminalEffect(PlanetSideGUID(10), PlanetSideGUID(40), true)) expectMsg(LocalServiceResponse("/nowhere/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(PlanetSideGUID(1), true)))
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.ProximityTerminalEffect(PlanetSideGUID(40), true))) }
}
}
class ProximityTerminalEffectOffTest extends ActorTest {
ServiceManager.boot(system)
val service = system.actorOf(Props[LocalService], "l_service")
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.GUID = PlanetSideGUID(1)
"LocalService" should {
"pass ProximityTerminalEffect (false)" in {
service ! Service.Join("nowhere")
service ! Terminal.StopProximityEffect(terminal)
expectMsg(LocalServiceResponse("/nowhere/Local", PlanetSideGUID(0), LocalResponse.ProximityTerminalEffect(PlanetSideGUID(1), false)))
} }
} }
} }

View file

@ -9,7 +9,6 @@ import net.psforever.objects.serverobject.locks.IFFLock
import net.psforever.objects.serverobject.mblocker.Locker import net.psforever.objects.serverobject.mblocker.Locker
import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.serverobject.pad.VehicleSpawnPad
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder, StructureType, WarpGate} import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder, StructureType, WarpGate}
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, ProximityTerminal, Terminal} import net.psforever.objects.serverobject.terminals.{CaptureTerminal, ProximityTerminal, Terminal}
import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.serverobject.tube.SpawnTube
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
@ -56,7 +55,7 @@ object Maps {
LocalObject(380, Door.Constructor) LocalObject(380, Door.Constructor)
LocalObject(381, Door.Constructor) LocalObject(381, Door.Constructor)
LocalObject(382, Door.Constructor) LocalObject(382, Door.Constructor)
LocalObject(383, Door.Constructor(Vector3(2674.0938f, 4317.367f, 44.59375f), Vector3(0.0f, 0.0f, 180.0f))) LocalObject(383, Door.Constructor(Vector3(2674.0938f, 4317.367f, 44.59375f), Vector3.z(180.0f)))
LocalObject(384, Door.Constructor(Vector3(2674.086f, 4321.6953f, 44.59375f), Vector3(0.0f, 357.1875f, 357.1875f))) LocalObject(384, Door.Constructor(Vector3(2674.086f, 4321.6953f, 44.59375f), Vector3(0.0f, 357.1875f, 357.1875f)))
LocalObject(385, Door.Constructor) LocalObject(385, Door.Constructor)
LocalObject(386, Door.Constructor(Vector3(2692.086f, 4316.5703f, 52.03125f), Vector3(0.0f, 2.8125f, 270.0f))) LocalObject(386, Door.Constructor(Vector3(2692.086f, 4316.5703f, 52.03125f), Vector3(0.0f, 2.8125f, 270.0f)))
@ -78,7 +77,7 @@ object Maps {
LocalObject(701, Door.Constructor) LocalObject(701, Door.Constructor)
LocalObject(703, Door.Constructor) LocalObject(703, Door.Constructor)
LocalObject(716, Door.Constructor) LocalObject(716, Door.Constructor)
LocalObject(920, Door.Constructor(Vector3(2708.1953f, 4319.9766f, 39.59375f), Vector3(0.0f, 0.0f, 92.8125f))) LocalObject(920, Door.Constructor(Vector3(2708.1953f, 4319.9766f, 39.59375f), Vector3.z(92.8125f)))
//Akkan Locks //Akkan Locks
LocalObject(968, IFFLock.Constructor) LocalObject(968, IFFLock.Constructor)
@ -182,16 +181,16 @@ object Maps {
LocalObject(516, Door.Constructor) LocalObject(516, Door.Constructor)
LocalObject(517, Door.Constructor) LocalObject(517, Door.Constructor)
LocalObject(518, Door.Constructor) LocalObject(518, Door.Constructor)
LocalObject(519, Door.Constructor(Vector3(4342.7266f, 5833.461f, 77.890625f), Vector3(0, 0, 272))) LocalObject(519, Door.Constructor(Vector3(4342.7266f, 5833.461f, 77.890625f), Vector3.z(272)))
LocalObject(520, Door.Constructor) LocalObject(520, Door.Constructor)
LocalObject(521, Door.Constructor) LocalObject(521, Door.Constructor)
LocalObject(522, Door.Constructor(Vector3(4395.7188f, 5908.2188f, 92.90625f), Vector3(0, 0, 2))) LocalObject(522, Door.Constructor(Vector3(4395.7188f, 5908.2188f, 92.90625f), Vector3.z(2)))
LocalObject(523, Door.Constructor(Vector3(4402.086f, 5891.914f, 92.90625f), Vector3(0, 0, 182))) LocalObject(523, Door.Constructor(Vector3(4402.086f, 5891.914f, 92.90625f), Vector3.z(182)))
LocalObject(524, Door.Constructor) LocalObject(524, Door.Constructor)
LocalObject(535, Door.Constructor) LocalObject(535, Door.Constructor)
LocalObject(536, Door.Constructor) LocalObject(536, Door.Constructor)
LocalObject(537, Door.Constructor) LocalObject(537, Door.Constructor)
LocalObject(653, Door.Constructor(Vector3(4339.6953f, 5973.828f, 77.875f), Vector3(0, 0, 2))) LocalObject(653, Door.Constructor(Vector3(4339.6953f, 5973.828f, 77.875f), Vector3.z(2)))
LocalObject(657, Door.Constructor) LocalObject(657, Door.Constructor)
LocalObject(810, Door.Constructor) LocalObject(810, Door.Constructor)
LocalObject(811, Door.Constructor) LocalObject(811, Door.Constructor)
@ -200,19 +199,19 @@ object Maps {
LocalObject(814, Door.Constructor) LocalObject(814, Door.Constructor)
LocalObject(815, Door.Constructor) LocalObject(815, Door.Constructor)
LocalObject(816, Door.Constructor) LocalObject(816, Door.Constructor)
LocalObject(817, Door.Constructor(Vector3(4380.5938f, 5892.047f, 92.890625f), Vector3(0, 0, 2))) LocalObject(817, Door.Constructor(Vector3(4380.5938f, 5892.047f, 92.890625f), Vector3.z(2)))
LocalObject(818, Door.Constructor) LocalObject(818, Door.Constructor)
LocalObject(819, Door.Constructor) LocalObject(819, Door.Constructor)
LocalObject(820, Door.Constructor) LocalObject(820, Door.Constructor)
LocalObject(821, Door.Constructor) LocalObject(821, Door.Constructor)
LocalObject(822, Door.Constructor) LocalObject(822, Door.Constructor)
LocalObject(823, Door.Constructor) LocalObject(823, Door.Constructor)
LocalObject(824, Door.Constructor(Vector3(4404.328f, 5883.4453f, 70.40625f), Vector3(0, 0, 182))) LocalObject(824, Door.Constructor(Vector3(4404.328f, 5883.4453f, 70.40625f), Vector3.z(182)))
LocalObject(825, Door.Constructor(Vector3(4405.133f, 5907.117f, 70.390625f), Vector3(0, 0, 2))) LocalObject(825, Door.Constructor(Vector3(4405.133f, 5907.117f, 70.390625f), Vector3.z(2)))
LocalObject(826, Door.Constructor(Vector3(4413.3984f, 5914.9688f, 62.890625f), Vector3(0, 0, 182))) LocalObject(826, Door.Constructor(Vector3(4413.3984f, 5914.9688f, 62.890625f), Vector3.z(182)))
LocalObject(827, Door.Constructor(Vector3(4416.4297f, 5886.867f, 62.890625f), Vector3(0, 0, 272))) LocalObject(827, Door.Constructor(Vector3(4416.4297f, 5886.867f, 62.890625f), Vector3.z(272)))
LocalObject(828, Door.Constructor) LocalObject(828, Door.Constructor)
LocalObject(925, Door.Constructor(Vector3(4424.492f, 5884.75f, 77.953125f), Vector3(0, 0, 182))) LocalObject(925, Door.Constructor(Vector3(4424.492f, 5884.75f, 77.953125f), Vector3.z(182)))
LocalObject(973, IFFLock.Constructor) LocalObject(973, IFFLock.Constructor)
LocalObject(980, IFFLock.Constructor) LocalObject(980, IFFLock.Constructor)
LocalObject(1142, IFFLock.Constructor) LocalObject(1142, IFFLock.Constructor)
@ -229,9 +228,9 @@ object Maps {
LocalObject(2016, Terminal.Constructor(order_terminal)) LocalObject(2016, Terminal.Constructor(order_terminal))
LocalObject(2017, Terminal.Constructor(order_terminal)) LocalObject(2017, Terminal.Constructor(order_terminal))
LocalObject(2658, ResourceSilo.Constructor) LocalObject(2658, ResourceSilo.Constructor)
LocalObject(2724, SpawnTube.Constructor(Vector3(4396.7656f, 5888.258f, 71.15625f), Vector3(0, 0, 92))) LocalObject(2724, SpawnTube.Constructor(Vector3(4396.7656f, 5888.258f, 71.15625f), Vector3.z(92)))
LocalObject(2725, SpawnTube.Constructor(Vector3(4397.211f, 5895.547f, 71.15625f), Vector3(0, 0, 92))) LocalObject(2725, SpawnTube.Constructor(Vector3(4397.211f, 5895.547f, 71.15625f), Vector3.z(92)))
LocalObject(2726, SpawnTube.Constructor(Vector3(4397.2344f, 5902.8203f, 71.15625f), Vector3(0, 0, 92))) LocalObject(2726, SpawnTube.Constructor(Vector3(4397.2344f, 5902.8203f, 71.15625f), Vector3.z(92)))
LocalObject(2948, Door.Constructor) //spawn tube door LocalObject(2948, Door.Constructor) //spawn tube door
LocalObject(2949, Door.Constructor) //spawn tube door LocalObject(2949, Door.Constructor) //spawn tube door
LocalObject(2950, Door.Constructor) //spawn tube door LocalObject(2950, Door.Constructor) //spawn tube door
@ -239,11 +238,11 @@ object Maps {
LocalObject(2854, Terminal.Constructor(spawn_terminal)) LocalObject(2854, Terminal.Constructor(spawn_terminal))
LocalObject(2859, Terminal.Constructor(spawn_terminal)) LocalObject(2859, Terminal.Constructor(spawn_terminal))
LocalObject(3072, Terminal.Constructor(ground_vehicle_terminal)) LocalObject(3072, Terminal.Constructor(ground_vehicle_terminal))
LocalObject(1888, VehicleSpawnPad.Constructor(Vector3(4337.0f, 5903.0f, 58.0f), Vector3(0f, 0f, 0f))) LocalObject(1888, VehicleSpawnPad.Constructor(Vector3(4337.0f, 5903.0f, 58.0f), Vector3.Zero))
LocalObject(176, Terminal.Constructor(air_vehicle_terminal)) LocalObject(176, Terminal.Constructor(air_vehicle_terminal))
LocalObject(1889, VehicleSpawnPad.Constructor(Vector3(4386.0f, 5928.0f, 93.0f), Vector3(0f, 0f, 0f))) LocalObject(1889, VehicleSpawnPad.Constructor(Vector3(4386.0f, 5928.0f, 93.0f), Vector3.Zero))
LocalObject(177, Terminal.Constructor(air_vehicle_terminal)) LocalObject(177, Terminal.Constructor(air_vehicle_terminal))
LocalObject(1890, VehicleSpawnPad.Constructor(Vector3(4407.0f, 5927.0f, 93.0f), Vector3(0f, 0f, 0f))) LocalObject(1890, VehicleSpawnPad.Constructor(Vector3(4407.0f, 5927.0f, 93.0f), Vector3.Zero))
// LocalObject(1909, ProximityTerminal.Constructor(medical_terminal)) // LocalObject(1909, ProximityTerminal.Constructor(medical_terminal))
// LocalObject(1910, ProximityTerminal.Constructor(medical_terminal)) // LocalObject(1910, ProximityTerminal.Constructor(medical_terminal))
@ -340,14 +339,14 @@ object Maps {
LocalBuilding(10, FoundationBuilder(Building.Structure(StructureType.Facility, Vector3(3749f, 5477f, 0)))) // Todo change pos LocalBuilding(10, FoundationBuilder(Building.Structure(StructureType.Facility, Vector3(3749f, 5477f, 0)))) // Todo change pos
LocalObject(223, CaptureTerminal.Constructor(capture_terminal)) LocalObject(223, CaptureTerminal.Constructor(capture_terminal))
LocalObject(464, Door.Constructor) LocalObject(464, Door.Constructor)
LocalObject(470, Door.Constructor(Vector3(3645.3984f, 5451.9688f, 88.890625f), Vector3(0, 0, 182))) LocalObject(470, Door.Constructor(Vector3(3645.3984f, 5451.9688f, 88.890625f), Vector3.z(182)))
LocalObject(471, Door.Constructor) LocalObject(471, Door.Constructor)
LocalObject(472, Door.Constructor) LocalObject(472, Door.Constructor)
LocalObject(473, Door.Constructor) LocalObject(473, Door.Constructor)
LocalObject(474, Door.Constructor) LocalObject(474, Door.Constructor)
LocalObject(475, Door.Constructor(Vector3(3740.7422f, 5477.8906f, 98.890625f), Vector3(0, 0, 92))) LocalObject(475, Door.Constructor(Vector3(3740.7422f, 5477.8906f, 98.890625f), Vector3.z(92)))
LocalObject(476, Door.Constructor) LocalObject(476, Door.Constructor)
LocalObject(481, Door.Constructor(Vector3(3758.25f, 5497.8047f, 98.890625f), Vector3(0, 0, 182))) LocalObject(481, Door.Constructor(Vector3(3758.25f, 5497.8047f, 98.890625f), Vector3.z(182)))
LocalObject(482, Door.Constructor) LocalObject(482, Door.Constructor)
LocalObject(483, Door.Constructor) LocalObject(483, Door.Constructor)
LocalObject(484, Door.Constructor) LocalObject(484, Door.Constructor)
@ -359,22 +358,22 @@ object Maps {
LocalObject(768, Door.Constructor) LocalObject(768, Door.Constructor)
LocalObject(769, Door.Constructor) LocalObject(769, Door.Constructor)
LocalObject(770, Door.Constructor) LocalObject(770, Door.Constructor)
LocalObject(771, Door.Constructor(Vector3(3738.039f, 5470.0547f, 78.890625f), Vector3(0, 0, 272))) LocalObject(771, Door.Constructor(Vector3(3738.039f, 5470.0547f, 78.890625f), Vector3.z(272)))
LocalObject(772, Door.Constructor) LocalObject(772, Door.Constructor)
LocalObject(773, Door.Constructor) LocalObject(773, Door.Constructor)
LocalObject(774, Door.Constructor(Vector3(3741.5312f, 5457.7734f, 71.390625f), Vector3(0, 0, 2))) LocalObject(774, Door.Constructor(Vector3(3741.5312f, 5457.7734f, 71.390625f), Vector3.z(2)))
LocalObject(775, Door.Constructor) LocalObject(775, Door.Constructor)
LocalObject(776, Door.Constructor) LocalObject(776, Door.Constructor)
LocalObject(777, Door.Constructor) LocalObject(777, Door.Constructor)
LocalObject(778, Door.Constructor) LocalObject(778, Door.Constructor)
LocalObject(779, Door.Constructor(Vector3(3761.4531f, 5469.5703f, 78.890625f), Vector3(0, 0, 92))) LocalObject(779, Door.Constructor(Vector3(3761.4531f, 5469.5703f, 78.890625f), Vector3.z(92)))
LocalObject(780, Door.Constructor) LocalObject(780, Door.Constructor)
LocalObject(781, Door.Constructor) LocalObject(781, Door.Constructor)
LocalObject(782, Door.Constructor) LocalObject(782, Door.Constructor)
LocalObject(783, Door.Constructor) LocalObject(783, Door.Constructor)
LocalObject(784, Door.Constructor(Vector3(3806.3906f, 5504.9766f, 78.890625f), Vector3(0, 0, 182))) LocalObject(784, Door.Constructor(Vector3(3806.3906f, 5504.9766f, 78.890625f), Vector3.z(182)))
LocalObject(785, Door.Constructor(Vector3(3806.5938f, 5512.5703f, 78.890625f), Vector3(0, 0, 2))) LocalObject(785, Door.Constructor(Vector3(3806.5938f, 5512.5703f, 78.890625f), Vector3.z(2)))
LocalObject(923, Door.Constructor(Vector3(3762.7266f, 5477.539f, 88.953125f), Vector3(0, 0, 92))) LocalObject(923, Door.Constructor(Vector3(3762.7266f, 5477.539f, 88.953125f), Vector3.z(92)))
LocalObject(932, Door.Constructor) LocalObject(932, Door.Constructor)
LocalObject(933, Door.Constructor) LocalObject(933, Door.Constructor)
@ -409,30 +408,30 @@ object Maps {
LocalObject(1992, Terminal.Constructor(order_terminal)) LocalObject(1992, Terminal.Constructor(order_terminal))
LocalObject(1993, Terminal.Constructor(order_terminal)) LocalObject(1993, Terminal.Constructor(order_terminal))
LocalObject(1994, Terminal.Constructor(order_terminal)) LocalObject(1994, Terminal.Constructor(order_terminal))
LocalObject(2710, SpawnTube.Constructor(Vector3(3742.6016f, 5477.6797f, 79.640625f), Vector3(0, 0, 182))) LocalObject(2710, SpawnTube.Constructor(Vector3(3742.6016f, 5477.6797f, 79.640625f), Vector3.z(182)))
LocalObject(2713, SpawnTube.Constructor(Vector3(3749.9062f, 5477.711f, 79.640625f), Vector3(0, 0, 182))) LocalObject(2713, SpawnTube.Constructor(Vector3(3749.9062f, 5477.711f, 79.640625f), Vector3.z(182)))
LocalObject(2714, SpawnTube.Constructor(Vector3(3757.1875f, 5477.5312f, 79.640625f), Vector3(0, 0, 182))) LocalObject(2714, SpawnTube.Constructor(Vector3(3757.1875f, 5477.5312f, 79.640625f), Vector3.z(182)))
LocalObject(2934, Door.Constructor) //spawn tube door LocalObject(2934, Door.Constructor) //spawn tube door
LocalObject(2937, Door.Constructor) //spawn tube door LocalObject(2937, Door.Constructor) //spawn tube door
LocalObject(2938, Door.Constructor) //spawn tube door LocalObject(2938, Door.Constructor) //spawn tube door
LocalObject(2228, ProximityTerminal.Constructor(pad_landing)) LocalObject(2228, ProximityTerminal.Constructor(pad_landing_frame))
LocalObject(2229, Terminal.Constructor(pad_landing)) LocalObject(2229, Terminal.Constructor(air_rearm_terminal))
LocalObject(2231, ProximityTerminal.Constructor(pad_landing)) LocalObject(2231, ProximityTerminal.Constructor(pad_landing_frame))
LocalObject(2232, Terminal.Constructor(pad_landing)) LocalObject(2232, Terminal.Constructor(air_rearm_terminal))
LocalObject(2234, ProximityTerminal.Constructor(pad_landing)) LocalObject(2234, ProximityTerminal.Constructor(pad_landing_frame))
LocalObject(2235, Terminal.Constructor(pad_landing)) LocalObject(2235, Terminal.Constructor(air_rearm_terminal))
LocalObject(2237, ProximityTerminal.Constructor(pad_landing)) LocalObject(2237, ProximityTerminal.Constructor(pad_landing_frame))
LocalObject(2238, Terminal.Constructor(pad_landing)) LocalObject(2238, Terminal.Constructor(air_rearm_terminal))
LocalObject(2595, ProximityTerminal.Constructor(repair_silo)) LocalObject(2595, ProximityTerminal.Constructor(repair_silo))
LocalObject(2596, Terminal.Constructor(repair_silo)) LocalObject(2596, Terminal.Constructor(ground_rearm_terminal))
LocalObject(2599, ProximityTerminal.Constructor(repair_silo)) LocalObject(2599, ProximityTerminal.Constructor(repair_silo))
LocalObject(2600, Terminal.Constructor(repair_silo)) LocalObject(2600, Terminal.Constructor(ground_rearm_terminal))
LocalObject(3070, Terminal.Constructor(vehicle_terminal_combined)) LocalObject(3070, Terminal.Constructor(vehicle_terminal_combined))
LocalObject(1886, VehicleSpawnPad.Constructor(Vector3(3675.0f, 5458.0f, 89.0f), Vector3(0f, 0f, 0f))) LocalObject(1886, VehicleSpawnPad.Constructor(Vector3(3675.0f, 5458.0f, 89.0f), Vector3.Zero))
// LocalObject(169, ProximityTerminal.Constructor(adv_med_terminal)) // LocalObject(169, ProximityTerminal.Constructor(adv_med_terminal))
// LocalObject(1906, ProximityTerminal.Constructor(medical_terminal)) // LocalObject(1906, ProximityTerminal.Constructor(medical_terminal))
@ -560,20 +559,20 @@ object Maps {
LocalObject(563, Door.Constructor) LocalObject(563, Door.Constructor)
LocalObject(566, Door.Constructor) LocalObject(566, Door.Constructor)
LocalObject(567, Door.Constructor) LocalObject(567, Door.Constructor)
LocalObject(572, Door.Constructor(Vector3(4824.0703f, 5260.3516f, 78.703125f), Vector3(0, 0, 47))) LocalObject(572, Door.Constructor(Vector3(4824.0703f, 5260.3516f, 78.703125f), Vector3.z(47)))
LocalObject(573, Door.Constructor(Vector3(4833.711f, 5231.8203f, 71.25f), Vector3(0, 0, 47))) LocalObject(573, Door.Constructor(Vector3(4833.711f, 5231.8203f, 71.25f), Vector3.z(47)))
LocalObject(574, Door.Constructor(Vector3(4834.7188f, 5271.9766f, 71.25f), Vector3(0, 0, 317))) LocalObject(574, Door.Constructor(Vector3(4834.7188f, 5271.9766f, 71.25f), Vector3.z(317)))
LocalObject(575, Door.Constructor) LocalObject(575, Door.Constructor)
LocalObject(576, Door.Constructor(Vector3(4840.7734f, 5265.5f, 71.25f), Vector3(0, 0, 137))) LocalObject(576, Door.Constructor(Vector3(4840.7734f, 5265.5f, 71.25f), Vector3.z(137)))
LocalObject(577, Door.Constructor) LocalObject(577, Door.Constructor)
LocalObject(578, Door.Constructor(Vector3(4854.5625f, 5174.6562f, 66.25f), Vector3(0, 0, 227))) LocalObject(578, Door.Constructor(Vector3(4854.5625f, 5174.6562f, 66.25f), Vector3.z(227)))
LocalObject(579, Door.Constructor) LocalObject(579, Door.Constructor)
LocalObject(580, Door.Constructor) LocalObject(580, Door.Constructor)
LocalObject(585, Door.Constructor) LocalObject(585, Door.Constructor)
LocalObject(852, Door.Constructor(Vector3(4793.0547f, 5204.914f, 48.734375f), Vector3(0, 0, 47))) LocalObject(852, Door.Constructor(Vector3(4793.0547f, 5204.914f, 48.734375f), Vector3.z(47)))
LocalObject(853, Door.Constructor(Vector3(4799.3906f, 5216.047f, 56.234375f), Vector3(0, 0, 317))) LocalObject(853, Door.Constructor(Vector3(4799.3906f, 5216.047f, 56.234375f), Vector3.z(317)))
LocalObject(854, Door.Constructor) LocalObject(854, Door.Constructor)
LocalObject(855, Door.Constructor(Vector3(4815.5f, 5198.75f, 56.234375f), Vector3(0, 0, 137))) LocalObject(855, Door.Constructor(Vector3(4815.5f, 5198.75f, 56.234375f), Vector3.z(137)))
LocalObject(856, Door.Constructor) LocalObject(856, Door.Constructor)
LocalObject(857, Door.Constructor) LocalObject(857, Door.Constructor)
LocalObject(858, Door.Constructor) LocalObject(858, Door.Constructor)
@ -583,18 +582,18 @@ object Maps {
LocalObject(862, Door.Constructor) LocalObject(862, Door.Constructor)
LocalObject(863, Door.Constructor) LocalObject(863, Door.Constructor)
LocalObject(864, Door.Constructor) LocalObject(864, Door.Constructor)
LocalObject(865, Door.Constructor(Vector3(4837.3047f, 5169.672f, 48.75f), Vector3(0, 0, 227))) LocalObject(865, Door.Constructor(Vector3(4837.3047f, 5169.672f, 48.75f), Vector3.z(227)))
LocalObject(866, Door.Constructor(Vector3(4842.9844f, 5174.8906f, 48.75f), Vector3(0, 0, 47))) LocalObject(866, Door.Constructor(Vector3(4842.9844f, 5174.8906f, 48.75f), Vector3.z(47)))
LocalObject(867, Door.Constructor) LocalObject(867, Door.Constructor)
LocalObject(868, Door.Constructor) LocalObject(868, Door.Constructor)
LocalObject(869, Door.Constructor) LocalObject(869, Door.Constructor)
LocalObject(870, Door.Constructor) LocalObject(870, Door.Constructor)
LocalObject(871, Door.Constructor) LocalObject(871, Door.Constructor)
LocalObject(872, Door.Constructor(Vector3(4857.0547f, 5247.992f, 48.734375f), Vector3(0, 0, 317))) LocalObject(872, Door.Constructor(Vector3(4857.0547f, 5247.992f, 48.734375f), Vector3.z(317)))
LocalObject(873, Door.Constructor) LocalObject(873, Door.Constructor)
LocalObject(874, Door.Constructor) LocalObject(874, Door.Constructor)
LocalObject(875, Door.Constructor) LocalObject(875, Door.Constructor)
LocalObject(927, Door.Constructor(Vector3(4810.4297f, 5243.0703f, 66.296875f), Vector3(0, 0, 227))) LocalObject(927, Door.Constructor(Vector3(4810.4297f, 5243.0703f, 66.296875f), Vector3.z(227)))
LocalObject(975, IFFLock.Constructor) LocalObject(975, IFFLock.Constructor)
LocalObject(1182, IFFLock.Constructor) LocalObject(1182, IFFLock.Constructor)
@ -618,15 +617,15 @@ object Maps {
LocalObject(2041, Terminal.Constructor(order_terminal)) LocalObject(2041, Terminal.Constructor(order_terminal))
LocalObject(2042, Terminal.Constructor(order_terminal)) LocalObject(2042, Terminal.Constructor(order_terminal))
LocalObject(2043, Terminal.Constructor(order_terminal)) LocalObject(2043, Terminal.Constructor(order_terminal))
LocalObject(2740, SpawnTube.Constructor(Vector3(4808.0234f, 5217.9375f, 57f), Vector3(0, 0, 227))) LocalObject(2740, SpawnTube.Constructor(Vector3(4808.0234f, 5217.9375f, 57f), Vector3.z(227)))
LocalObject(2741, SpawnTube.Constructor(Vector3(4812.992f, 5212.6016f, 57f), Vector3(0, 0, 227))) LocalObject(2741, SpawnTube.Constructor(Vector3(4812.992f, 5212.6016f, 57f), Vector3.z(227)))
LocalObject(2742, SpawnTube.Constructor(Vector3(4818.047f, 5207.3125f, 57f), Vector3(0, 0, 227))) LocalObject(2742, SpawnTube.Constructor(Vector3(4818.047f, 5207.3125f, 57f), Vector3.z(227)))
LocalObject(2964, Door.Constructor) //spawn tube door LocalObject(2964, Door.Constructor) //spawn tube door
LocalObject(2965, Door.Constructor) //spawn tube door LocalObject(2965, Door.Constructor) //spawn tube door
LocalObject(2966, Door.Constructor) //spawn tube door LocalObject(2966, Door.Constructor) //spawn tube door
LocalObject(3074, Terminal.Constructor(vehicle_terminal_combined)) LocalObject(3074, Terminal.Constructor(vehicle_terminal_combined))
LocalObject(1892, VehicleSpawnPad.Constructor(Vector3(4834.0f, 5185.0f, 67.0f), Vector3(0f, 0f, 45.0f))) LocalObject(1892, VehicleSpawnPad.Constructor(Vector3(4834.0f, 5185.0f, 67.0f), Vector3.z(45.0f)))
// LocalObject(1912, ProximityTerminal.Constructor(medical_terminal)) // LocalObject(1912, ProximityTerminal.Constructor(medical_terminal))
// LocalObject(1913, ProximityTerminal.Constructor(medical_terminal)) // LocalObject(1913, ProximityTerminal.Constructor(medical_terminal))
@ -729,12 +728,12 @@ object Maps {
LocalObject(2797, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2797, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2973, Door.Constructor) LocalObject(2973, Door.Constructor)
LocalObject(2974, Door.Constructor) LocalObject(2974, Door.Constructor)
LocalObject(590, Door.Constructor(Vector3(5405.992f, 4220.1797f, 39.1875f), Vector3(0, 0, 180))) LocalObject(590, Door.Constructor(Vector3(5405.992f, 4220.1797f, 39.1875f), Vector3.z(180)))
LocalObject(591, Door.Constructor(Vector3(5405.992f, 4220.1797f, 49.1875f), Vector3(0, 0, 180))) LocalObject(591, Door.Constructor(Vector3(5405.992f, 4220.1797f, 49.1875f), Vector3.z(180)))
LocalObject(592, Door.Constructor(Vector3(5405.992f, 4220.1797f, 69.25f), Vector3(0, 0, 180))) LocalObject(592, Door.Constructor(Vector3(5405.992f, 4220.1797f, 69.25f), Vector3.z(180)))
LocalObject(595, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 69.25f), Vector3(0, 0, 0))) LocalObject(595, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 69.25f), Vector3.Zero))
LocalObject(593, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 39.1875f), Vector3(0, 0, 0))) LocalObject(593, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 39.1875f), Vector3.Zero))
LocalObject(594, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 49.1875f), Vector3(0, 0, 0))) LocalObject(594, Door.Constructor(Vector3(5405.9844f, 4235.8047f, 49.1875f), Vector3.Zero))
LocalObject(1208, IFFLock.Constructor) LocalObject(1208, IFFLock.Constructor)
LocalObject(1209, IFFLock.Constructor) LocalObject(1209, IFFLock.Constructor)
LocalObject(1210, IFFLock.Constructor) LocalObject(1210, IFFLock.Constructor)
@ -744,8 +743,8 @@ object Maps {
LocalObject(2053, Terminal.Constructor(order_terminal)) LocalObject(2053, Terminal.Constructor(order_terminal))
LocalObject(2054, Terminal.Constructor(order_terminal)) LocalObject(2054, Terminal.Constructor(order_terminal))
LocalObject(2055, Terminal.Constructor(order_terminal)) LocalObject(2055, Terminal.Constructor(order_terminal))
LocalObject(2749, SpawnTube.Constructor(respawn_tube_tower, Vector3(5404.8125f, 4215.7344f, 29.484375f), Vector3(0, 0, 90))) LocalObject(2749, SpawnTube.Constructor(respawn_tube_tower, Vector3(5404.8125f, 4215.7344f, 29.484375f), Vector3.z(90)))
LocalObject(2750, SpawnTube.Constructor(respawn_tube_tower, Vector3(5404.7656f, 4232.1562f, 29.484375f), Vector3(0, 0, 90))) LocalObject(2750, SpawnTube.Constructor(respawn_tube_tower, Vector3(5404.7656f, 4232.1562f, 29.484375f), Vector3.z(90)))
ObjectToBuilding(2797, 25) ObjectToBuilding(2797, 25)
ObjectToBuilding(2973, 25) ObjectToBuilding(2973, 25)
@ -781,10 +780,10 @@ object Maps {
LocalObject(2792, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2792, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2957, Door.Constructor) LocalObject(2957, Door.Constructor)
LocalObject(2958, Door.Constructor) LocalObject(2958, Door.Constructor)
LocalObject(542, Door.Constructor(Vector3(4625.9844f, 5910.211f, 55.75f), Vector3(0, 0, 180))) LocalObject(542, Door.Constructor(Vector3(4625.9844f, 5910.211f, 55.75f), Vector3.z(180)))
LocalObject(543, Door.Constructor(Vector3(4625.9844f, 5910.211f, 75.75f), Vector3(0, 0, 180))) LocalObject(543, Door.Constructor(Vector3(4625.9844f, 5910.211f, 75.75f), Vector3.z(180)))
LocalObject(544, Door.Constructor(Vector3(4626.0312f, 5925.836f, 55.75f), Vector3(0, 0, 0))) LocalObject(544, Door.Constructor(Vector3(4626.0312f, 5925.836f, 55.75f), Vector3.Zero))
LocalObject(545, Door.Constructor(Vector3(4626.0312f, 5925.836f, 75.75f), Vector3(0, 0, 0))) LocalObject(545, Door.Constructor(Vector3(4626.0312f, 5925.836f, 75.75f), Vector3.Zero))
LocalObject(1164, IFFLock.Constructor) LocalObject(1164, IFFLock.Constructor)
LocalObject(1165, IFFLock.Constructor) LocalObject(1165, IFFLock.Constructor)
LocalObject(1166, IFFLock.Constructor) LocalObject(1166, IFFLock.Constructor)
@ -792,8 +791,8 @@ object Maps {
LocalObject(2027, Terminal.Constructor(order_terminal)) LocalObject(2027, Terminal.Constructor(order_terminal))
LocalObject(2028, Terminal.Constructor(order_terminal)) LocalObject(2028, Terminal.Constructor(order_terminal))
LocalObject(2029, Terminal.Constructor(order_terminal)) LocalObject(2029, Terminal.Constructor(order_terminal))
LocalObject(2733, SpawnTube.Constructor(respawn_tube_tower, Vector3(4624.758f, 5905.7344f, 45.984375f), Vector3(0, 0, 90))) LocalObject(2733, SpawnTube.Constructor(respawn_tube_tower, Vector3(4624.758f, 5905.7344f, 45.984375f), Vector3.z(90)))
LocalObject(2734, SpawnTube.Constructor(respawn_tube_tower, Vector3(4624.7266f, 5922.1484f, 45.984375f), Vector3(0, 0, 90))) LocalObject(2734, SpawnTube.Constructor(respawn_tube_tower, Vector3(4624.7266f, 5922.1484f, 45.984375f), Vector3.z(90)))
ObjectToBuilding(2792, 33) ObjectToBuilding(2792, 33)
ObjectToBuilding(2957, 33) ObjectToBuilding(2957, 33)
@ -823,10 +822,10 @@ object Maps {
LocalObject(2789, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2789, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2951, Door.Constructor) LocalObject(2951, Door.Constructor)
LocalObject(2952, Door.Constructor) LocalObject(2952, Door.Constructor)
LocalObject(525, Door.Constructor(Vector3(4423.9766f, 4850.164f, 86.203125f), Vector3(0, 0, 180))) LocalObject(525, Door.Constructor(Vector3(4423.9766f, 4850.164f, 86.203125f), Vector3.z(180)))
LocalObject(526, Door.Constructor(Vector3(4423.9766f, 4850.164f, 106.140625f), Vector3(0, 0, 180))) LocalObject(526, Door.Constructor(Vector3(4423.9766f, 4850.164f, 106.140625f), Vector3.z(180)))
LocalObject(527, Door.Constructor(Vector3(4423.9688f, 4865.8594f, 86.203125f), Vector3(0, 0, 0))) LocalObject(527, Door.Constructor(Vector3(4423.9688f, 4865.8594f, 86.203125f), Vector3.Zero))
LocalObject(528, Door.Constructor(Vector3(4423.9688f, 4865.8594f, 106.140625f), Vector3(0, 0, 0))) LocalObject(528, Door.Constructor(Vector3(4423.9688f, 4865.8594f, 106.140625f), Vector3.Zero))
LocalObject(1155, IFFLock.Constructor) LocalObject(1155, IFFLock.Constructor)
LocalObject(1156, IFFLock.Constructor) LocalObject(1156, IFFLock.Constructor)
LocalObject(1150, IFFLock.Constructor) LocalObject(1150, IFFLock.Constructor)
@ -834,8 +833,8 @@ object Maps {
LocalObject(2018, Terminal.Constructor(order_terminal)) LocalObject(2018, Terminal.Constructor(order_terminal))
LocalObject(2019, Terminal.Constructor(order_terminal)) LocalObject(2019, Terminal.Constructor(order_terminal))
LocalObject(2020, Terminal.Constructor(order_terminal)) LocalObject(2020, Terminal.Constructor(order_terminal))
LocalObject(2727, SpawnTube.Constructor(respawn_tube_tower, Vector3(4422.8203f, 4845.711f, 76.4375f), Vector3(0, 0, 90))) LocalObject(2727, SpawnTube.Constructor(respawn_tube_tower, Vector3(4422.8203f, 4845.711f, 76.4375f), Vector3.z(90)))
LocalObject(2728, SpawnTube.Constructor(respawn_tube_tower, Vector3(4422.7344f, 4862.1406f, 76.4375f), Vector3(0, 0, 90))) LocalObject(2728, SpawnTube.Constructor(respawn_tube_tower, Vector3(4422.7344f, 4862.1406f, 76.4375f), Vector3.z(90)))
ObjectToBuilding(2789, 34) ObjectToBuilding(2789, 34)
ObjectToBuilding(2951, 34) ObjectToBuilding(2951, 34)
@ -865,12 +864,12 @@ object Maps {
LocalObject(2779, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2779, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2917, Door.Constructor) LocalObject(2917, Door.Constructor)
LocalObject(2918, Door.Constructor) LocalObject(2918, Door.Constructor)
LocalObject(414, Door.Constructor(Vector3(3098.0f, 5032.1484f, 81.9375f), Vector3(0, 0, 180))) LocalObject(414, Door.Constructor(Vector3(3098.0f, 5032.1484f, 81.9375f), Vector3.z(180)))
LocalObject(415, Door.Constructor(Vector3(3098.0f, 5032.1484f, 91.875f), Vector3(0, 0, 180))) LocalObject(415, Door.Constructor(Vector3(3098.0f, 5032.1484f, 91.875f), Vector3.z(180)))
LocalObject(416, Door.Constructor(Vector3(3098.0f, 5032.1484f, 111.875f), Vector3(0, 0, 180))) LocalObject(416, Door.Constructor(Vector3(3098.0f, 5032.1484f, 111.875f), Vector3.z(180)))
LocalObject(417, Door.Constructor(Vector3(3097.9922f, 5047.875f, 81.953125f), Vector3(0, 0, 0))) LocalObject(417, Door.Constructor(Vector3(3097.9922f, 5047.875f, 81.953125f), Vector3.Zero))
LocalObject(418, Door.Constructor(Vector3(3097.9922f, 5047.875f, 91.875f), Vector3(0, 0, 0))) LocalObject(418, Door.Constructor(Vector3(3097.9922f, 5047.875f, 91.875f), Vector3.Zero))
LocalObject(419, Door.Constructor(Vector3(3097.9922f, 5047.875f, 111.875f), Vector3(0, 0, 0))) LocalObject(419, Door.Constructor(Vector3(3097.9922f, 5047.875f, 111.875f), Vector3.Zero))
LocalObject(1062, IFFLock.Constructor) LocalObject(1062, IFFLock.Constructor)
LocalObject(1063, IFFLock.Constructor) LocalObject(1063, IFFLock.Constructor)
LocalObject(1064, IFFLock.Constructor) LocalObject(1064, IFFLock.Constructor)
@ -880,8 +879,8 @@ object Maps {
LocalObject(1966, Terminal.Constructor(order_terminal)) LocalObject(1966, Terminal.Constructor(order_terminal))
LocalObject(1967, Terminal.Constructor(order_terminal)) LocalObject(1967, Terminal.Constructor(order_terminal))
LocalObject(1968, Terminal.Constructor(order_terminal)) LocalObject(1968, Terminal.Constructor(order_terminal))
LocalObject(2693, SpawnTube.Constructor(respawn_tube_tower, Vector3(3096.6562f, 5027.742f, 72.1875f), Vector3(0, 0, 90))) LocalObject(2693, SpawnTube.Constructor(respawn_tube_tower, Vector3(3096.6562f, 5027.742f, 72.1875f), Vector3.z(90)))
LocalObject(2694, SpawnTube.Constructor(respawn_tube_tower, Vector3(3096.7812f, 5044.1562f, 72.1875f), Vector3(0, 0, 90))) LocalObject(2694, SpawnTube.Constructor(respawn_tube_tower, Vector3(3096.7812f, 5044.1562f, 72.1875f), Vector3.z(90)))
ObjectToBuilding(2779, 35) ObjectToBuilding(2779, 35)
ObjectToBuilding(2917, 35) ObjectToBuilding(2917, 35)
@ -917,10 +916,10 @@ object Maps {
LocalObject(2785, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2785, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2935, Door.Constructor) LocalObject(2935, Door.Constructor)
LocalObject(2936, Door.Constructor) LocalObject(2936, Door.Constructor)
LocalObject(477, Door.Constructor(Vector3(3750.0f, 6040.164f, 56.203125f), Vector3(0, 0, 180))) LocalObject(477, Door.Constructor(Vector3(3750.0f, 6040.164f, 56.203125f), Vector3.z(180)))
LocalObject(478, Door.Constructor(Vector3(3750.0f, 6040.164f, 76.15625f), Vector3(0, 0, 180))) LocalObject(478, Door.Constructor(Vector3(3750.0f, 6040.164f, 76.15625f), Vector3.z(180)))
LocalObject(479, Door.Constructor(Vector3(3750.0078f, 6055.789f, 56.203125f), Vector3(0, 0, 0))) LocalObject(479, Door.Constructor(Vector3(3750.0078f, 6055.789f, 56.203125f), Vector3.Zero))
LocalObject(480, Door.Constructor(Vector3(3750.0078f, 6055.789f, 76.15625f), Vector3(0, 0, 0))) LocalObject(480, Door.Constructor(Vector3(3750.0078f, 6055.789f, 76.15625f), Vector3.Zero))
LocalObject(1109, IFFLock.Constructor) LocalObject(1109, IFFLock.Constructor)
LocalObject(1110, IFFLock.Constructor) LocalObject(1110, IFFLock.Constructor)
LocalObject(1111, IFFLock.Constructor) LocalObject(1111, IFFLock.Constructor)
@ -928,8 +927,8 @@ object Maps {
LocalObject(1995, Terminal.Constructor(order_terminal)) LocalObject(1995, Terminal.Constructor(order_terminal))
LocalObject(1996, Terminal.Constructor(order_terminal)) LocalObject(1996, Terminal.Constructor(order_terminal))
LocalObject(1997, Terminal.Constructor(order_terminal)) LocalObject(1997, Terminal.Constructor(order_terminal))
LocalObject(2711, SpawnTube.Constructor(respawn_tube_tower, Vector3(3748.7266f, 6035.7344f, 46.453125f), Vector3(0, 0, 90))) LocalObject(2711, SpawnTube.Constructor(respawn_tube_tower, Vector3(3748.7266f, 6035.7344f, 46.453125f), Vector3.z(90)))
LocalObject(2712, SpawnTube.Constructor(respawn_tube_tower, Vector3(3748.6328f, 6052.125f, 46.453125f), Vector3(0, 0, 90))) LocalObject(2712, SpawnTube.Constructor(respawn_tube_tower, Vector3(3748.6328f, 6052.125f, 46.453125f), Vector3.z(90)))
ObjectToBuilding(2785, 36) ObjectToBuilding(2785, 36)
ObjectToBuilding(2935, 36) ObjectToBuilding(2935, 36)
@ -959,10 +958,10 @@ object Maps {
LocalObject(2795, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2795, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2969, Door.Constructor) LocalObject(2969, Door.Constructor)
LocalObject(2970, Door.Constructor) LocalObject(2970, Door.Constructor)
LocalObject(581, Door.Constructor(Vector3(4896.0156f, 4932.125f, 67.75f), Vector3(0, 0, 180))) LocalObject(581, Door.Constructor(Vector3(4896.0156f, 4932.125f, 67.75f), Vector3.z(180)))
LocalObject(582, Door.Constructor(Vector3(4895.992f, 4932.1484f, 87.75f), Vector3(0, 0, 180))) LocalObject(582, Door.Constructor(Vector3(4895.992f, 4932.1484f, 87.75f), Vector3.z(180)))
LocalObject(583, Door.Constructor(Vector3(4896.0156f, 4947.8516f, 67.75f), Vector3(0, 0, 0))) LocalObject(583, Door.Constructor(Vector3(4896.0156f, 4947.8516f, 67.75f), Vector3.Zero))
LocalObject(584, Door.Constructor(Vector3(4896.008f, 4947.8438f, 87.75f), Vector3(0, 0, 0))) LocalObject(584, Door.Constructor(Vector3(4896.008f, 4947.8438f, 87.75f), Vector3.Zero))
LocalObject(1199, IFFLock.Constructor) LocalObject(1199, IFFLock.Constructor)
LocalObject(1200, IFFLock.Constructor) LocalObject(1200, IFFLock.Constructor)
LocalObject(1197, IFFLock.Constructor) LocalObject(1197, IFFLock.Constructor)
@ -970,8 +969,8 @@ object Maps {
LocalObject(2047, Terminal.Constructor(order_terminal)) LocalObject(2047, Terminal.Constructor(order_terminal))
LocalObject(2048, Terminal.Constructor(order_terminal)) LocalObject(2048, Terminal.Constructor(order_terminal))
LocalObject(2049, Terminal.Constructor(order_terminal)) LocalObject(2049, Terminal.Constructor(order_terminal))
LocalObject(2745, SpawnTube.Constructor(respawn_tube_tower, Vector3(4894.7734f, 4927.742f, 57.984375f), Vector3(0, 0, 90))) LocalObject(2745, SpawnTube.Constructor(respawn_tube_tower, Vector3(4894.7734f, 4927.742f, 57.984375f), Vector3.z(90)))
LocalObject(2746, SpawnTube.Constructor(respawn_tube_tower, Vector3(4894.7734f, 4944.117f, 57.984375f), Vector3(0, 0, 90))) LocalObject(2746, SpawnTube.Constructor(respawn_tube_tower, Vector3(4894.7734f, 4944.117f, 57.984375f), Vector3.z(90)))
ObjectToBuilding(2795, 55) ObjectToBuilding(2795, 55)
ObjectToBuilding(2969, 55) ObjectToBuilding(2969, 55)
@ -1001,10 +1000,10 @@ object Maps {
LocalObject(2784, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2784, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2932, Door.Constructor) LocalObject(2932, Door.Constructor)
LocalObject(2933, Door.Constructor) LocalObject(2933, Door.Constructor)
LocalObject(466, Door.Constructor(Vector3(3592.0f, 5286.1562f, 69.390625f), Vector3(0, 0, 180))) LocalObject(466, Door.Constructor(Vector3(3592.0f, 5286.1562f, 69.390625f), Vector3.z(180)))
LocalObject(467, Door.Constructor(Vector3(3592.0f, 5286.1562f, 89.453125f), Vector3(0, 0, 180))) LocalObject(467, Door.Constructor(Vector3(3592.0f, 5286.1562f, 89.453125f), Vector3.z(180)))
LocalObject(468, Door.Constructor(Vector3(3592.0f, 5301.797f, 69.390625f), Vector3(0, 0, 0))) LocalObject(468, Door.Constructor(Vector3(3592.0f, 5301.797f, 69.390625f), Vector3.Zero))
LocalObject(469, Door.Constructor(Vector3(3592.0f, 5301.797f, 89.4375f), Vector3(0, 0, 0))) LocalObject(469, Door.Constructor(Vector3(3592.0f, 5301.797f, 89.4375f), Vector3.Zero))
LocalObject(1101, IFFLock.Constructor) LocalObject(1101, IFFLock.Constructor)
LocalObject(1102, IFFLock.Constructor) LocalObject(1102, IFFLock.Constructor)
LocalObject(1103, IFFLock.Constructor) LocalObject(1103, IFFLock.Constructor)
@ -1012,8 +1011,8 @@ object Maps {
LocalObject(1988, Terminal.Constructor(order_terminal)) LocalObject(1988, Terminal.Constructor(order_terminal))
LocalObject(1989, Terminal.Constructor(order_terminal)) LocalObject(1989, Terminal.Constructor(order_terminal))
LocalObject(1990, Terminal.Constructor(order_terminal)) LocalObject(1990, Terminal.Constructor(order_terminal))
LocalObject(2708, SpawnTube.Constructor(respawn_tube_tower, Vector3(3590.9062f, 5281.742f, 59.6875f), Vector3(0, 0, 90))) LocalObject(2708, SpawnTube.Constructor(respawn_tube_tower, Vector3(3590.9062f, 5281.742f, 59.6875f), Vector3.z(90)))
LocalObject(2709, SpawnTube.Constructor(respawn_tube_tower, Vector3(3590.836f, 5298.1484f, 59.6875f), Vector3(0, 0, 90))) LocalObject(2709, SpawnTube.Constructor(respawn_tube_tower, Vector3(3590.836f, 5298.1484f, 59.6875f), Vector3.z(90)))
ObjectToBuilding(2784, 56) ObjectToBuilding(2784, 56)
ObjectToBuilding(2932, 56) ObjectToBuilding(2932, 56)
@ -1043,12 +1042,12 @@ object Maps {
LocalObject(2793, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2793, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2959, Door.Constructor) LocalObject(2959, Door.Constructor)
LocalObject(2960, Door.Constructor) LocalObject(2960, Door.Constructor)
LocalObject(546, Door.Constructor(Vector3(4669.992f, 6620.1562f, 42.875f), Vector3(0, 0, 180))) LocalObject(546, Door.Constructor(Vector3(4669.992f, 6620.1562f, 42.875f), Vector3.z(180)))
LocalObject(547, Door.Constructor(Vector3(4669.992f, 6620.1562f, 52.8125f), Vector3(0, 0, 180))) LocalObject(547, Door.Constructor(Vector3(4669.992f, 6620.1562f, 52.8125f), Vector3.z(180)))
LocalObject(548, Door.Constructor(Vector3(4669.992f, 6620.1562f, 72.8125f), Vector3(0, 0, 180))) LocalObject(548, Door.Constructor(Vector3(4669.992f, 6620.1562f, 72.8125f), Vector3.z(180)))
LocalObject(549, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 42.859375f), Vector3(0, 0, 0))) LocalObject(549, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 42.859375f), Vector3.Zero))
LocalObject(550, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 52.8125f), Vector3(0, 0, 0))) LocalObject(550, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 52.8125f), Vector3.Zero))
LocalObject(551, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 72.8125f), Vector3(0, 0, 0))) LocalObject(551, Door.Constructor(Vector3(4669.9844f, 6635.8203f, 72.8125f), Vector3.Zero))
LocalObject(1168, IFFLock.Constructor) LocalObject(1168, IFFLock.Constructor)
LocalObject(1169, IFFLock.Constructor) LocalObject(1169, IFFLock.Constructor)
LocalObject(1170, IFFLock.Constructor) LocalObject(1170, IFFLock.Constructor)
@ -1058,8 +1057,8 @@ object Maps {
LocalObject(2030, Terminal.Constructor(order_terminal)) LocalObject(2030, Terminal.Constructor(order_terminal))
LocalObject(2031, Terminal.Constructor(order_terminal)) LocalObject(2031, Terminal.Constructor(order_terminal))
LocalObject(2032, Terminal.Constructor(order_terminal)) LocalObject(2032, Terminal.Constructor(order_terminal))
LocalObject(2735, SpawnTube.Constructor(respawn_tube_tower, Vector3(4668.7656f, 6615.7344f, 33.109375f), Vector3(0, 0, 90))) LocalObject(2735, SpawnTube.Constructor(respawn_tube_tower, Vector3(4668.7656f, 6615.7344f, 33.109375f), Vector3.z(90)))
LocalObject(2736, SpawnTube.Constructor(respawn_tube_tower, Vector3(4668.742f, 6632.1562f, 33.109375f), Vector3(0, 0, 90))) LocalObject(2736, SpawnTube.Constructor(respawn_tube_tower, Vector3(4668.742f, 6632.1562f, 33.109375f), Vector3.z(90)))
ObjectToBuilding(2793, 59) ObjectToBuilding(2793, 59)
ObjectToBuilding(2959, 59) ObjectToBuilding(2959, 59)
@ -1095,10 +1094,10 @@ object Maps {
LocalObject(2778, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2778, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2914, Door.Constructor) LocalObject(2914, Door.Constructor)
LocalObject(2915, Door.Constructor) LocalObject(2915, Door.Constructor)
LocalObject(404, Door.Constructor(Vector3(3003.9688f, 5706.1484f, 56.3125f), Vector3(0, 0, 180))) LocalObject(404, Door.Constructor(Vector3(3003.9688f, 5706.1484f, 56.3125f), Vector3.z(180)))
LocalObject(405, Door.Constructor(Vector3(3003.9688f, 5706.1484f, 76.25f), Vector3(0, 0, 180))) LocalObject(405, Door.Constructor(Vector3(3003.9688f, 5706.1484f, 76.25f), Vector3.z(180)))
LocalObject(406, Door.Constructor(Vector3(3004.0469f, 5721.875f, 56.328125f), Vector3(0, 0, 0))) LocalObject(406, Door.Constructor(Vector3(3004.0469f, 5721.875f, 56.328125f), Vector3.Zero))
LocalObject(407, Door.Constructor(Vector3(3004.0469f, 5721.875f, 76.25f), Vector3(0, 0, 0))) LocalObject(407, Door.Constructor(Vector3(3004.0469f, 5721.875f, 76.25f), Vector3.Zero))
LocalObject(1054, IFFLock.Constructor) LocalObject(1054, IFFLock.Constructor)
LocalObject(1055, IFFLock.Constructor) LocalObject(1055, IFFLock.Constructor)
LocalObject(1056, IFFLock.Constructor) LocalObject(1056, IFFLock.Constructor)
@ -1106,8 +1105,8 @@ object Maps {
LocalObject(1960, Terminal.Constructor(order_terminal)) LocalObject(1960, Terminal.Constructor(order_terminal))
LocalObject(1961, Terminal.Constructor(order_terminal)) LocalObject(1961, Terminal.Constructor(order_terminal))
LocalObject(1962, Terminal.Constructor(order_terminal)) LocalObject(1962, Terminal.Constructor(order_terminal))
LocalObject(2690, SpawnTube.Constructor(respawn_tube_tower, Vector3(3022.711f, 5701.758f, 47f), Vector3(0, 0, 90))) LocalObject(2690, SpawnTube.Constructor(respawn_tube_tower, Vector3(3022.711f, 5701.758f, 47f), Vector3.z(90)))
LocalObject(2691, SpawnTube.Constructor(respawn_tube_tower, Vector3(3002.7188f, 5718.1562f, 47f), Vector3(0, 0, 90))) LocalObject(2691, SpawnTube.Constructor(respawn_tube_tower, Vector3(3002.7188f, 5718.1562f, 47f), Vector3.z(90)))
ObjectToBuilding(2778, 65) ObjectToBuilding(2778, 65)
ObjectToBuilding(2914, 65) ObjectToBuilding(2914, 65)
@ -1137,7 +1136,7 @@ object Maps {
// // BFR test // // BFR test
//// LocalObject(199, Terminal.Constructor(vehicle_terminal_combined))) //// LocalObject(199, Terminal.Constructor(vehicle_terminal_combined)))
//// LocalObject(505, //// LocalObject(505,
//// VehicleSpawnPad.Constructor(Vector3(3707.0f, 5522.0f, 89.0f), Vector3(0f, 0f, 0f)) //// VehicleSpawnPad.Constructor(Vector3(3707.0f, 5522.0f, 89.0f), Vector3.Zero)
//// )) //TODO guid not correct //// )) //TODO guid not correct
//// ObjectToBuilding(199, 30) //// ObjectToBuilding(199, 30)
//// ObjectToBuilding(505, 30) //// ObjectToBuilding(505, 30)
@ -1194,21 +1193,21 @@ object Maps {
LocalObject(371, Door.Constructor) //courtyard LocalObject(371, Door.Constructor) //courtyard
LocalObject(372, Door.Constructor) //courtyard LocalObject(372, Door.Constructor) //courtyard
LocalObject(373, Door.Constructor) //courtyard LocalObject(373, Door.Constructor) //courtyard
LocalObject(375, Door.Constructor(Vector3(3924.0f, 4231.2656f, 271.82812f), Vector3(0, 0, 180))) //2nd level door, south LocalObject(375, Door.Constructor(Vector3(3924.0f, 4231.2656f, 271.82812f), Vector3.z(180))) //2nd level door, south
LocalObject(376, Door.Constructor(Vector3(3924.0f, 4240.2656f, 271.82812f), Vector3(0, 0, 0))) //2nd level door, north LocalObject(376, Door.Constructor(Vector3(3924.0f, 4240.2656f, 271.82812f), Vector3.Zero)) //2nd level door, north
LocalObject(383, Door.Constructor) //courtyard LocalObject(383, Door.Constructor) //courtyard
LocalObject(384, Door.Constructor(Vector3(3939.6328f, 4232.547f, 279.26562f), Vector3(0, 0, 270))) //3rd floor door LocalObject(384, Door.Constructor(Vector3(3939.6328f, 4232.547f, 279.26562f), Vector3.z(270))) //3rd floor door
LocalObject(385, Door.Constructor) //courtyard LocalObject(385, Door.Constructor) //courtyard
LocalObject(387, Door.Constructor(Vector3(3951.9531f, 4260.008f, 271.82812f), Vector3(0, 0, 270))) //2nd level door, stairwell LocalObject(387, Door.Constructor(Vector3(3951.9531f, 4260.008f, 271.82812f), Vector3.z(270))) //2nd level door, stairwell
LocalObject(391, Door.Constructor) //courtyard LocalObject(391, Door.Constructor) //courtyard
LocalObject(393, Door.Constructor(Vector3(3997.8984f, 4344.3203f, 271.8125f), Vector3(0, 0, 0))) //air term building, upstairs door LocalObject(393, Door.Constructor(Vector3(3997.8984f, 4344.3203f, 271.8125f), Vector3.Zero)) //air term building, upstairs door
LocalObject(394, Door.Constructor(Vector3(3999.9766f, 4314.3203f, 266.82812f), Vector3(0, 0, 270))) //air term building, f.door LocalObject(394, Door.Constructor(Vector3(3999.9766f, 4314.3203f, 266.82812f), Vector3.z(270))) //air term building, f.door
LocalObject(396, Door.Constructor) //courtyard LocalObject(396, Door.Constructor) //courtyard
LocalObject(398, Door.Constructor) //courtyard LocalObject(398, Door.Constructor) //courtyard
LocalObject(399, Door.Constructor) //courtyard LocalObject(399, Door.Constructor) //courtyard
LocalObject(402, Door.Constructor) //courtyard LocalObject(402, Door.Constructor) //courtyard
LocalObject(403, Door.Constructor) //courtyard LocalObject(403, Door.Constructor) //courtyard
LocalObject(404, Door.Constructor(Vector3(4060.0078f, 4319.9766f, 266.8125f), Vector3(0, 0, 0))) //b.door LocalObject(404, Door.Constructor(Vector3(4060.0078f, 4319.9766f, 266.8125f), Vector3.Zero)) //b.door
LocalObject(603, Door.Constructor) LocalObject(603, Door.Constructor)
LocalObject(604, Door.Constructor) LocalObject(604, Door.Constructor)
LocalObject(605, Door.Constructor) LocalObject(605, Door.Constructor)
@ -1218,19 +1217,19 @@ object Maps {
LocalObject(611, Door.Constructor) LocalObject(611, Door.Constructor)
LocalObject(614, Door.Constructor) LocalObject(614, Door.Constructor)
LocalObject(619, Door.Constructor) LocalObject(619, Door.Constructor)
LocalObject(620, Door.Constructor(Vector3(3983.9531f, 4299.992f, 249.29688f), Vector3(0, 0, 90))) //generator room door LocalObject(620, Door.Constructor(Vector3(3983.9531f, 4299.992f, 249.29688f), Vector3.z(90))) //generator room door
LocalObject(621, Door.Constructor) LocalObject(621, Door.Constructor)
LocalObject(622, Door.Constructor(Vector3(3988.0078f, 4248.0156f, 256.82812f), Vector3(0, 0, 180))) //spawn room door LocalObject(622, Door.Constructor(Vector3(3988.0078f, 4248.0156f, 256.82812f), Vector3.z(180))) //spawn room door
LocalObject(623, Door.Constructor(Vector3(3988.0078f, 4271.9766f, 256.79688f), Vector3(0, 0, 0))) //spawn room door LocalObject(623, Door.Constructor(Vector3(3988.0078f, 4271.9766f, 256.79688f), Vector3.Zero)) //spawn room door
LocalObject(630, Door.Constructor(Vector3(4000.0078f, 4252.0f, 249.29688f), Vector3(0, 0, 270))) //spawn room door LocalObject(630, Door.Constructor(Vector3(4000.0078f, 4252.0f, 249.29688f), Vector3.z(270))) //spawn room door
LocalObject(631, Door.Constructor) //spawn room door, kitchen LocalObject(631, Door.Constructor) //spawn room door, kitchen
LocalObject(634, Door.Constructor) //air term building, interior LocalObject(634, Door.Constructor) //air term building, interior
LocalObject(638, Door.Constructor(Vector3(4016.0078f, 4212.008f, 249.29688f), Vector3(0, 0, 270))) //cc door LocalObject(638, Door.Constructor(Vector3(4016.0078f, 4212.008f, 249.29688f), Vector3.z(270))) //cc door
LocalObject(642, Door.Constructor(Vector3(4023.9844f, 4212.008f, 249.32812f), Vector3(0, 0, 90))) //cc door, interior LocalObject(642, Door.Constructor(Vector3(4023.9844f, 4212.008f, 249.32812f), Vector3.z(90))) //cc door, interior
LocalObject(643, Door.Constructor) //cc door, exterior LocalObject(643, Door.Constructor) //cc door, exterior
LocalObject(645, Door.Constructor) //b.door, interior LocalObject(645, Door.Constructor) //b.door, interior
LocalObject(646, Door.Constructor) //b.door, interior LocalObject(646, Door.Constructor) //b.door, interior
LocalObject(715, Door.Constructor(Vector3(3961.5938f ,4235.8125f, 266.84375f), Vector3(0, 0, 90))) //f.door LocalObject(715, Door.Constructor(Vector3(3961.5938f ,4235.8125f, 266.84375f), Vector3.z(90))) //f.door
LocalObject(751, IFFLock.Constructor) LocalObject(751, IFFLock.Constructor)
LocalObject(860, IFFLock.Constructor) LocalObject(860, IFFLock.Constructor)
LocalObject(863, IFFLock.Constructor) LocalObject(863, IFFLock.Constructor)
@ -1265,8 +1264,8 @@ object Maps {
LocalObject(1428, FacilityTurret.Constructor(manned_turret)) LocalObject(1428, FacilityTurret.Constructor(manned_turret))
LocalObject(1431, FacilityTurret.Constructor(manned_turret)) LocalObject(1431, FacilityTurret.Constructor(manned_turret))
LocalObject(1432, FacilityTurret.Constructor(manned_turret)) LocalObject(1432, FacilityTurret.Constructor(manned_turret))
LocalObject(1492, ProximityTerminal.Constructor(medical_terminal)) //lobby LocalObject(1492, ProximityTerminal.Constructor(medical_terminal, Vector3(3944.8672f, 4211.336f, 266.85938f))) //lobby
LocalObject(1494, ProximityTerminal.Constructor(medical_terminal)) //kitchen LocalObject(1494, ProximityTerminal.Constructor(medical_terminal, Vector3(4008.3594f, 4269.25f, 249.35938f))) //kitchen
LocalObject(1564, Terminal.Constructor(order_terminal)) LocalObject(1564, Terminal.Constructor(order_terminal))
LocalObject(1568, Terminal.Constructor(order_terminal)) LocalObject(1568, Terminal.Constructor(order_terminal))
LocalObject(1569, Terminal.Constructor(order_terminal)) LocalObject(1569, Terminal.Constructor(order_terminal))
@ -1275,21 +1274,21 @@ object Maps {
LocalObject(1576, Terminal.Constructor(order_terminal)) LocalObject(1576, Terminal.Constructor(order_terminal))
LocalObject(1577, Terminal.Constructor(order_terminal)) LocalObject(1577, Terminal.Constructor(order_terminal))
LocalObject(1578, Terminal.Constructor(order_terminal)) LocalObject(1578, Terminal.Constructor(order_terminal))
LocalObject(1744, ProximityTerminal.Constructor(pad_landing)) //air pad A LocalObject(1744, ProximityTerminal.Constructor(pad_landing_frame, Vector3(3924.8203f, 4331.789f, 275.92188f))) //air pad North
LocalObject(1745, Terminal.Constructor(pad_landing)) //air pad A LocalObject(1745, Terminal.Constructor(air_rearm_terminal)) //air pad North
LocalObject(1747, ProximityTerminal.Constructor(pad_landing)) //air pad B LocalObject(1747, ProximityTerminal.Constructor(pad_landing_frame, Vector3(3941.8984f, 4288.9844f, 273.20312f))) //air pad South
LocalObject(1748, Terminal.Constructor(pad_landing)) //air pad B LocalObject(1748, Terminal.Constructor(air_rearm_terminal)) //air pad South
LocalObject(1756, ProximityTerminal.Constructor(pad_landing)) //air pad C LocalObject(1756, ProximityTerminal.Constructor(pad_landing_frame, Vector3(3995.3516f, 4251.547f, 280.375f))) //air pad West
LocalObject(1757, Terminal.Constructor(pad_landing)) //air pad C LocalObject(1757, Terminal.Constructor(air_rearm_terminal)) //air pad West
LocalObject(1765, ProximityTerminal.Constructor(pad_landing)) //air pad D LocalObject(1765, ProximityTerminal.Constructor(pad_landing_frame, Vector3(4027.5469f, 4268.414f, 275.92188f))) //air pad East
LocalObject(1766, Terminal.Constructor(pad_landing)) //air pad D LocalObject(1766, Terminal.Constructor(air_rearm_terminal)) //air pad East
LocalObject(2145, SpawnTube.Constructor(Vector3(3980.4062f, 4252.7656f, 257.5625f), Vector3(0, 0, 90))) LocalObject(2145, SpawnTube.Constructor(Vector3(3980.4062f, 4252.7656f, 257.5625f), Vector3.z(90)))
LocalObject(2146, SpawnTube.Constructor(Vector3(3980.4062f, 4259.992f, 257.5625f), Vector3(0, 0, 90))) LocalObject(2146, SpawnTube.Constructor(Vector3(3980.4062f, 4259.992f, 257.5625f), Vector3.z(90)))
LocalObject(2147, SpawnTube.Constructor(Vector3(3980.4062f, 4267.3047f, 257.5625f), Vector3(0, 0, 90))) LocalObject(2147, SpawnTube.Constructor(Vector3(3980.4062f, 4267.3047f, 257.5625f), Vector3.z(90)))
LocalObject(2049, ProximityTerminal.Constructor(repair_silo)) //repair terminal A LocalObject(2049, ProximityTerminal.Constructor(repair_silo, Vector3(3882.0078f, 4278.2266f, 266.4375f))) //repair terminal West
LocalObject(2050, Terminal.Constructor(repair_silo)) //rearm terminal A LocalObject(2050, Terminal.Constructor(ground_rearm_terminal)) //rearm terminal West
LocalObject(2061, ProximityTerminal.Constructor(repair_silo)) //repair terminal B LocalObject(2061, ProximityTerminal.Constructor(repair_silo, Vector3(4053.3516f, 4281.1562f, 266.4375f))) //repair terminal East
LocalObject(2062, Terminal.Constructor(repair_silo)) //rearm terminal B LocalObject(2062, Terminal.Constructor(ground_rearm_terminal)) //rearm terminal East
LocalObject(2094, ResourceSilo.Constructor) LocalObject(2094, ResourceSilo.Constructor)
LocalObject(2239, Terminal.Constructor(spawn_terminal)) LocalObject(2239, Terminal.Constructor(spawn_terminal))
LocalObject(2244, Terminal.Constructor(spawn_terminal)) LocalObject(2244, Terminal.Constructor(spawn_terminal))
@ -1309,7 +1308,7 @@ object Maps {
) )
LocalObject(224, Terminal.Constructor(dropship_vehicle_terminal)) LocalObject(224, Terminal.Constructor(dropship_vehicle_terminal))
LocalObject(223, LocalObject(223,
VehicleSpawnPad.Constructor(Vector3(4012.3594f, 4364.8047f, 271.90625f), Vector3(0f, 0f, 0f)) VehicleSpawnPad.Constructor(Vector3(4012.3594f, 4364.8047f, 271.90625f), Vector3.Zero)
) )
ObjectToBuilding(180, 2) ObjectToBuilding(180, 2)
ObjectToBuilding(222, 2) ObjectToBuilding(222, 2)
@ -1475,12 +1474,12 @@ object Maps {
def Building48() : Unit = { def Building48() : Unit = {
//North Anguta Watchtower //North Anguta Watchtower
LocalBuilding(48, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(3864.2266f, 4518.0234f, 0)))) LocalBuilding(48, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(3864.2266f, 4518.0234f, 0))))
LocalObject(364, Door.Constructor(Vector3(3871.9688f, 4509.992f, 269.65625f), Vector3(0f, 0f, 180f))) //s1 LocalObject(364, Door.Constructor(Vector3(3871.9688f, 4509.992f, 269.65625f), Vector3.z(180f))) //s1
LocalObject(365, Door.Constructor(Vector3(3871.9688f, 4509.992f, 279.57812f), Vector3(0f, 0f, 180f))) //s2 LocalObject(365, Door.Constructor(Vector3(3871.9688f, 4509.992f, 279.57812f), Vector3.z(180f))) //s2
LocalObject(366, Door.Constructor(Vector3(3871.9688f, 4509.992f, 299.57812f), Vector3(0f, 0f, 180f))) //s3 LocalObject(366, Door.Constructor(Vector3(3871.9688f, 4509.992f, 299.57812f), Vector3.z(180f))) //s3
LocalObject(367, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 269.65625f), Vector3(0f, 0f, 0f))) //n1 LocalObject(367, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 269.65625f), Vector3.Zero)) //n1
LocalObject(368, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 279.57812f), Vector3(0f, 0f, 0f))) //n2 LocalObject(368, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 279.57812f), Vector3.Zero)) //n2
LocalObject(369, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 299.57812f), Vector3(0f, 0f, 0f))) //n3 LocalObject(369, Door.Constructor(Vector3(3871.9688f, 4525.9844f, 299.57812f), Vector3.Zero)) //n3
LocalObject(854, IFFLock.Constructor) LocalObject(854, IFFLock.Constructor)
LocalObject(855, IFFLock.Constructor) LocalObject(855, IFFLock.Constructor)
LocalObject(856, IFFLock.Constructor) LocalObject(856, IFFLock.Constructor)
@ -1498,8 +1497,8 @@ object Maps {
LocalObject(1561, Terminal.Constructor(order_terminal)) LocalObject(1561, Terminal.Constructor(order_terminal))
LocalObject(1562, Terminal.Constructor(order_terminal)) LocalObject(1562, Terminal.Constructor(order_terminal))
LocalObject(1563, Terminal.Constructor(order_terminal)) LocalObject(1563, Terminal.Constructor(order_terminal))
LocalObject(2138, SpawnTube.Constructor(respawn_tube_tower, Vector3(3870.9688f, 4505.7266f, 259.875f), Vector3(0, 0, 90))) LocalObject(2138, SpawnTube.Constructor(respawn_tube_tower, Vector3(3870.9688f, 4505.7266f, 259.875f), Vector3.z(90)))
LocalObject(2139, SpawnTube.Constructor(respawn_tube_tower, Vector3(3870.9688f, 4522.1562f, 259.875f), Vector3(0, 0, 90))) LocalObject(2139, SpawnTube.Constructor(respawn_tube_tower, Vector3(3870.9688f, 4522.1562f, 259.875f), Vector3.z(90)))
LocalObject(2197, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2197, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2315, Door.Constructor) //spawn tube door LocalObject(2315, Door.Constructor) //spawn tube door
LocalObject(2316, Door.Constructor) //spawn tube door LocalObject(2316, Door.Constructor) //spawn tube door
@ -1542,10 +1541,10 @@ object Maps {
def Building49() : Unit = { def Building49() : Unit = {
//North Akna Air Tower //North Akna Air Tower
LocalBuilding(49, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(4358.3203f, 3989.5625f, 0)))) LocalBuilding(49, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(4358.3203f, 3989.5625f, 0))))
LocalObject(430, Door.Constructor(Vector3(4366.0156f, 3981.9922f, 237.96875f), Vector3(0f, 0f, 180f))) //s1 LocalObject(430, Door.Constructor(Vector3(4366.0156f, 3981.9922f, 237.96875f), Vector3.z(180f))) //s1
LocalObject(431, Door.Constructor(Vector3(4366.0156f, 3981.9922f, 257.89062f), Vector3(0f, 0f, 180f))) //s2 LocalObject(431, Door.Constructor(Vector3(4366.0156f, 3981.9922f, 257.89062f), Vector3.z(180f))) //s2
LocalObject(432, Door.Constructor(Vector3(4366.0156f, 3997.9297f, 237.96875f), Vector3(0f, 0f, 0f))) //n1 LocalObject(432, Door.Constructor(Vector3(4366.0156f, 3997.9297f, 237.96875f), Vector3.Zero)) //n1
LocalObject(433, Door.Constructor(Vector3(4366.0156f, 3997.9297f, 257.89062f), Vector3(0f, 0f, 0f))) //n2 LocalObject(433, Door.Constructor(Vector3(4366.0156f, 3997.9297f, 257.89062f), Vector3.Zero)) //n2
LocalObject(902, IFFLock.Constructor) LocalObject(902, IFFLock.Constructor)
LocalObject(903, IFFLock.Constructor) LocalObject(903, IFFLock.Constructor)
LocalObject(906, IFFLock.Constructor) LocalObject(906, IFFLock.Constructor)
@ -1563,12 +1562,12 @@ object Maps {
LocalObject(1591, Terminal.Constructor(order_terminal)) LocalObject(1591, Terminal.Constructor(order_terminal))
LocalObject(1592, Terminal.Constructor(order_terminal)) LocalObject(1592, Terminal.Constructor(order_terminal))
LocalObject(1593, Terminal.Constructor(order_terminal)) LocalObject(1593, Terminal.Constructor(order_terminal))
LocalObject(1846, ProximityTerminal.Constructor(pad_landing)) //air pad S LocalObject(1846, ProximityTerminal.Constructor(pad_landing_tower_frame, Vector3(4352.3984f, 3984.7422f, 266.125f))) //air pad South
LocalObject(1847, Terminal.Constructor(pad_landing)) //air pad S LocalObject(1847, Terminal.Constructor(air_rearm_terminal)) //air pad South
LocalObject(1849, ProximityTerminal.Constructor(pad_landing)) //air pad N LocalObject(1849, ProximityTerminal.Constructor(pad_landing_tower_frame, Vector3(4352.3984f, 3995.2812f, 266.125f))) //air pad North
LocalObject(1850, Terminal.Constructor(pad_landing)) //air pad N LocalObject(1850, Terminal.Constructor(air_rearm_terminal)) //air pad North
LocalObject(2156, SpawnTube.Constructor(respawn_tube_tower, Vector3(4364.633f, 3994.125f, 228.1875f), Vector3(0, 0, 90))) LocalObject(2156, SpawnTube.Constructor(respawn_tube_tower, Vector3(4364.633f, 3994.125f, 228.1875f), Vector3.z(90)))
LocalObject(2157, SpawnTube.Constructor(respawn_tube_tower, Vector3(4364.633f, 3977.7266f, 228.1875f), Vector3(0, 0, 90))) LocalObject(2157, SpawnTube.Constructor(respawn_tube_tower, Vector3(4364.633f, 3977.7266f, 228.1875f), Vector3.z(90)))
LocalObject(2203, CaptureTerminal.Constructor(secondary_capture)) LocalObject(2203, CaptureTerminal.Constructor(secondary_capture))
LocalObject(2333, Door.Constructor) //spawn tube door LocalObject(2333, Door.Constructor) //spawn tube door
LocalObject(2334, Door.Constructor) //spawn tube door LocalObject(2334, Door.Constructor) //spawn tube door
@ -1653,7 +1652,7 @@ object Maps {
LocalBuilding(67, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1, 0, 0)))) LocalBuilding(67, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1, 0, 0))))
LocalObject(282, Door.Constructor) //spawn tube door LocalObject(282, Door.Constructor) //spawn tube door
LocalObject(396, Door.Constructor) //entrance LocalObject(396, Door.Constructor) //entrance
LocalObject(766, SpawnTube.Constructor(Vector3(3138.0f, 2875.0f, 36.2f), Vector3(0, 0, 180))) LocalObject(766, SpawnTube.Constructor(Vector3(3138.0f, 2875.0f, 36.2f), Vector3.z(180)))
ObjectToBuilding(282, 67) ObjectToBuilding(282, 67)
ObjectToBuilding(396, 67) ObjectToBuilding(396, 67)
ObjectToBuilding(766, 67) ObjectToBuilding(766, 67)
@ -1686,7 +1685,7 @@ object Maps {
LocalBuilding(67, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1, 0, 0)))) LocalBuilding(67, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1, 0, 0))))
LocalObject(282, Door.Constructor) //spawn tube door LocalObject(282, Door.Constructor) //spawn tube door
LocalObject(396, Door.Constructor) //entrance LocalObject(396, Door.Constructor) //entrance
LocalObject(766, SpawnTube.Constructor(Vector3(3138.0f, 2875.0f, 36.2f), Vector3(0, 0, 180))) LocalObject(766, SpawnTube.Constructor(Vector3(3138.0f, 2875.0f, 36.2f), Vector3.z(180)))
ObjectToBuilding(282, 67) ObjectToBuilding(282, 67)
ObjectToBuilding(396, 67) ObjectToBuilding(396, 67)
ObjectToBuilding(766, 67) ObjectToBuilding(766, 67)
@ -1758,10 +1757,10 @@ object Maps {
LocalObject(691, Locker.Constructor) LocalObject(691, Locker.Constructor)
LocalObject(692, Locker.Constructor) LocalObject(692, Locker.Constructor)
LocalObject(693, Locker.Constructor) LocalObject(693, Locker.Constructor)
LocalObject(778, ProximityTerminal.Constructor(medical_terminal)) LocalObject(778, ProximityTerminal.Constructor(medical_terminal, Vector3(3617.3516f, 2785.3281f, 93.65625f))) //medical terminal Southwest
LocalObject(779, ProximityTerminal.Constructor(medical_terminal)) LocalObject(779, ProximityTerminal.Constructor(medical_terminal, Vector3(3617.3516f, 2830.414f, 93.65625f))) //medical terminal Southeast
LocalObject(780, ProximityTerminal.Constructor(medical_terminal)) LocalObject(780, ProximityTerminal.Constructor(medical_terminal, Vector3(3758.7031f, 2785.3281f, 93.65625f))) //medical terminal Southeast
LocalObject(781, ProximityTerminal.Constructor(medical_terminal)) LocalObject(781, ProximityTerminal.Constructor(medical_terminal, Vector3(3758.7031f, 2830.414f, 93.65625f))) //medical terminal Northeast
LocalObject(842, Terminal.Constructor(order_terminal)) LocalObject(842, Terminal.Constructor(order_terminal))
LocalObject(843, Terminal.Constructor(order_terminal)) LocalObject(843, Terminal.Constructor(order_terminal))
LocalObject(844, Terminal.Constructor(order_terminal)) LocalObject(844, Terminal.Constructor(order_terminal))
@ -1835,10 +1834,10 @@ object Maps {
def Building29() : Unit = { def Building29() : Unit = {
//South Villa Gun Tower //South Villa Gun Tower
LocalBuilding(29, FoundationBuilder(Building.Structure(StructureType.Tower))) LocalBuilding(29, FoundationBuilder(Building.Structure(StructureType.Tower)))
LocalObject(330, Door.Constructor(Vector3(3979.9219f, 2592.0547f, 91.140625f), Vector3(0, 0, 180))) LocalObject(330, Door.Constructor(Vector3(3979.9219f, 2592.0547f, 91.140625f), Vector3.z(180)))
LocalObject(331, Door.Constructor(Vector3(3979.9219f, 2592.0547f, 111.140625f), Vector3(0, 0, 180))) LocalObject(331, Door.Constructor(Vector3(3979.9219f, 2592.0547f, 111.140625f), Vector3.z(180)))
LocalObject(332, Door.Constructor(Vector3(3979.9688f, 2608.0625f, 91.140625f), Vector3(0, 0, 0))) LocalObject(332, Door.Constructor(Vector3(3979.9688f, 2608.0625f, 91.140625f), Vector3.Zero))
LocalObject(333, Door.Constructor(Vector3(3979.9688f, 2608.0625f, 111.140625f), Vector3(0, 0, 0))) LocalObject(333, Door.Constructor(Vector3(3979.9688f, 2608.0625f, 111.140625f), Vector3.Zero))
LocalObject(556, IFFLock.Constructor) LocalObject(556, IFFLock.Constructor)
LocalObject(557, IFFLock.Constructor) LocalObject(557, IFFLock.Constructor)
LocalObject(558, IFFLock.Constructor) LocalObject(558, IFFLock.Constructor)
@ -1882,12 +1881,12 @@ object Maps {
LocalObject(433, Door.Constructor) //vr door LocalObject(433, Door.Constructor) //vr door
LocalObject(434, Door.Constructor) //vr door LocalObject(434, Door.Constructor) //vr door
LocalObject(435, Door.Constructor) //vr door LocalObject(435, Door.Constructor) //vr door
LocalObject(744, SpawnTube.Constructor(Vector3(3684.336f, 2709.0469f, 91.9f), Vector3(0, 0, 180))) LocalObject(744, SpawnTube.Constructor(Vector3(3684.336f, 2709.0469f, 91.9f), Vector3.z(180)))
LocalObject(745, SpawnTube.Constructor(Vector3(3684.336f, 2713.75f, 91.9f), Vector3(0, 0, 0))) LocalObject(745, SpawnTube.Constructor(Vector3(3684.336f, 2713.75f, 91.9f), Vector3.Zero))
LocalObject(746, SpawnTube.Constructor(Vector3(3690.9062f, 2708.4219f, 91.9f), Vector3(0, 0, 180))) LocalObject(746, SpawnTube.Constructor(Vector3(3690.9062f, 2708.4219f, 91.9f), Vector3.z(180)))
LocalObject(747, SpawnTube.Constructor(Vector3(3691.0703f, 2713.8672f, 91.9f), Vector3(0, 0, 0))) LocalObject(747, SpawnTube.Constructor(Vector3(3691.0703f, 2713.8672f, 91.9f), Vector3.Zero))
LocalObject(748, SpawnTube.Constructor(Vector3(3697.664f, 2708.3984f, 91.9f), Vector3(0, 0, 180))) LocalObject(748, SpawnTube.Constructor(Vector3(3697.664f, 2708.3984f, 91.9f), Vector3.z(180)))
LocalObject(749, SpawnTube.Constructor(Vector3(3697.711f, 2713.2344f, 91.9f), Vector3(0, 0, 0))) LocalObject(749, SpawnTube.Constructor(Vector3(3697.711f, 2713.2344f, 91.9f), Vector3.Zero))
LocalObject(852, Terminal.Constructor(order_terminal)) //s. wall LocalObject(852, Terminal.Constructor(order_terminal)) //s. wall
LocalObject(853, Terminal.Constructor(order_terminal)) //n. wall LocalObject(853, Terminal.Constructor(order_terminal)) //n. wall
LocalObject(854, Terminal.Constructor(order_terminal)) //s. wall LocalObject(854, Terminal.Constructor(order_terminal)) //s. wall
@ -1923,9 +1922,9 @@ object Maps {
} }
def Building51() : Unit = { def Building51() : Unit = {
//air terminal west of HART C //air terminal & silo west of HART C
LocalObject(12, ProximityTerminal.Constructor(repair_silo)) //repair terminal LocalObject(12, ProximityTerminal.Constructor(repair_silo, Vector3(3646.6328f, 2870.9062f, 91.046875f))) //repair terminal
LocalObject(13, Terminal.Constructor(repair_silo)) //rearm terminal LocalObject(13, Terminal.Constructor(ground_rearm_terminal)) //rearm terminal
LocalBuilding(51, FoundationBuilder(Building.Structure(StructureType.Platform))) LocalBuilding(51, FoundationBuilder(Building.Structure(StructureType.Platform)))
LocalObject(304, Terminal.Constructor(dropship_vehicle_terminal)) LocalObject(304, Terminal.Constructor(dropship_vehicle_terminal))
LocalObject(292, LocalObject(292,

View file

@ -90,8 +90,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
var spectator : Boolean = false var spectator : Boolean = false
var admin : Boolean = false var admin : Boolean = false
var usingMedicalTerminal : Option[PlanetSideGUID] = None var usingMedicalTerminal : Option[PlanetSideGUID] = None
var usingProximityTerminal : Set[PlanetSideGUID] = Set.empty
var delayedProximityTerminalResets : Map[PlanetSideGUID, Cancellable] = Map.empty
var controlled : Option[Int] = None var controlled : Option[Int] = None
//keep track of avatar's ServerVehicleOverride state //keep track of avatar's ServerVehicleOverride state
var traveler : Traveler = null var traveler : Traveler = null
@ -133,18 +131,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
LivePlayerList.Remove(sessionId) LivePlayerList.Remove(sessionId)
if(player != null && player.HasGUID) { if(player != null && player.HasGUID) {
val player_guid = player.GUID val player_guid = player.GUID
//proximity vehicle terminals must be considered too
delayedProximityTerminalResets.foreach({ case (_, task) => task.cancel })
usingProximityTerminal.foreach(term_guid => {
continent.GUID(term_guid) match {
case Some(obj : ProximityTerminal) =>
if(obj.NumberUsers > 0 && obj.RemoveUser(player_guid) == 0) {
//refer to ProximityTerminalControl when modernizng
localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, false))
}
case _ => ;
}
})
//handle orphaned deployables //handle orphaned deployables
DisownDeployables() DisownDeployables()
//clean up boomer triggers and telepads //clean up boomer triggers and telepads
@ -295,6 +281,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Terminal.TerminalMessage(tplayer, msg, order) => case Terminal.TerminalMessage(tplayer, msg, order) =>
HandleTerminalMessage(tplayer, msg, order) HandleTerminalMessage(tplayer, msg, order)
case ProximityUnit.Action(term, target) =>
SelectProximityUnitBehavior(term, target)
case VehicleServiceResponse(toChannel, guid, reply) => case VehicleServiceResponse(toChannel, guid, reply) =>
HandleVehicleServiceResponse(toChannel, guid, reply) HandleVehicleServiceResponse(toChannel, guid, reply)
@ -835,9 +824,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
case HackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction, tickAction) => case HackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction, tickAction) =>
HandleHackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction, tickAction) HandleHackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction, tickAction)
case DelayedProximityUnitStop(terminal) =>
StopUsingProximityUnit(terminal)
case Vitality.DamageResolution(target : Vehicle) => case Vitality.DamageResolution(target : Vehicle) =>
HandleVehicleDamageResolution(target) HandleVehicleDamageResolution(target)
@ -1304,10 +1290,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ObjectDeleteMessage(object_guid, unk)) sendResponse(ObjectDeleteMessage(object_guid, unk))
} }
case LocalResponse.ProximityTerminalEffect(object_guid, effectState) => case LocalResponse.ProximityTerminalEffect(object_guid, true) =>
if(tplayer_guid != guid) { sendResponse(ProximityTerminalUseMessage(PlanetSideGUID(0), object_guid, true))
sendResponse(ProximityTerminalUseMessage(PlanetSideGUID(0), object_guid, effectState))
} case LocalResponse.ProximityTerminalEffect(object_guid, false) =>
sendResponse(ProximityTerminalUseMessage(PlanetSideGUID(0), object_guid, false))
ForgetAllProximityTerminals(object_guid)
case LocalResponse.RouterTelepadMessage(msg) => case LocalResponse.RouterTelepadMessage(msg) =>
sendResponse(ChatMsg(ChatMessageType.UNK_229, false, "", msg, None)) sendResponse(ChatMsg(ChatMessageType.UNK_229, false, "", msg, None))
@ -1569,6 +1557,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
else { else {
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.BuyEquipment(item) => case Terminal.BuyEquipment(item) =>
tplayer.Fit(item) match { tplayer.Fit(item) match {
@ -1578,6 +1567,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case None => case None =>
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.SellEquipment() => case Terminal.SellEquipment() =>
tplayer.FreeHand.Equipment match { tplayer.FreeHand.Equipment match {
@ -1589,6 +1579,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case None => case None =>
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Sell, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Sell, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.InfantryLoadout(exosuit, subtype, holsters, inventory) => case Terminal.InfantryLoadout(exosuit, subtype, holsters, inventory) =>
log.info(s"$tplayer wants to change equipment loadout to their option #${msg.unk1 + 1}") log.info(s"$tplayer wants to change equipment loadout to their option #${msg.unk1 + 1}")
@ -1657,6 +1648,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
}) ++ dropHolsters ++ dropInventory).foreach(entry => { }) ++ dropHolsters ++ dropInventory).foreach(entry => {
continent.Ground ! Zone.Ground.DropItem(entry.obj, pos, orient) continent.Ground ! Zone.Ground.DropItem(entry.obj, pos, orient)
}) })
lastTerminalOrderFulfillment = true
case Terminal.VehicleLoadout(definition, weapons, inventory) => case Terminal.VehicleLoadout(definition, weapons, inventory) =>
log.info(s"$tplayer wants to change their vehicle equipment loadout to their option #${msg.unk1 + 1}") log.info(s"$tplayer wants to change their vehicle equipment loadout to their option #${msg.unk1 + 1}")
@ -1704,6 +1696,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.error(s"can not apply the loadout - can not find a vehicle") log.error(s"can not apply the loadout - can not find a vehicle")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.LearnCertification(cert) => case Terminal.LearnCertification(cert) =>
val name = tplayer.Name val name = tplayer.Name
@ -1726,6 +1719,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.warn(s"$name already knows the $cert certification, so he can't learn it") log.warn(s"$name already knows the $cert certification, so he can't learn it")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.SellCertification(cert) => case Terminal.SellCertification(cert) =>
val name = tplayer.Name val name = tplayer.Name
@ -1749,6 +1743,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.warn(s"$name doesn't know what a $cert certification is, so he can't forget it") log.warn(s"$name doesn't know what a $cert certification is, so he can't forget it")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.LearnImplant(implant) => case Terminal.LearnImplant(implant) =>
val terminal_guid = msg.terminal_guid val terminal_guid = msg.terminal_guid
@ -1790,6 +1785,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Learn, false)) sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Learn, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.SellImplant(implant) => case Terminal.SellImplant(implant) =>
val terminal_guid = msg.terminal_guid val terminal_guid = msg.terminal_guid
@ -1825,16 +1821,17 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, false)) sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, false))
} }
lastTerminalOrderFulfillment = true
case Terminal.BuyVehicle(vehicle, weapons, trunk) => case Terminal.BuyVehicle(vehicle, weapons, trunk) =>
continent.Map.TerminalToSpawnPad.get(msg.terminal_guid.guid) match { continent.Map.TerminalToSpawnPad.get(msg.terminal_guid.guid) match {
case Some(pad_guid) => case Some(pad_guid) =>
val pad = continent.GUID(pad_guid).get.asInstanceOf[VehicleSpawnPad] val pad = continent.GUID(pad_guid).get.asInstanceOf[VehicleSpawnPad]
vehicle.Faction = tplayer.Faction vehicle.Faction = tplayer.Faction
vehicle.Continent = continent.Id
vehicle.Position = pad.Position vehicle.Position = pad.Position
vehicle.Orientation = pad.Orientation vehicle.Orientation = pad.Orientation
//default loadout, weapons //default loadout, weapons
log.info(s"default weapons: ${weapons.size}")
val vWeapons = vehicle.Weapons val vWeapons = vehicle.Weapons
weapons.foreach(entry => { weapons.foreach(entry => {
val index = entry.start val index = entry.start
@ -1843,11 +1840,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
slot.Equipment = None slot.Equipment = None
slot.Equipment = entry.obj slot.Equipment = entry.obj
case None => case None =>
log.warn(s"applying default loadout to $vehicle, can not find a mounted weapon @ $index") log.warn(s"applying default loadout to $vehicle on spawn, but can not find a mounted weapon @ $index")
} }
}) })
//default loadout, trunk //default loadout, trunk
log.info(s"default trunk: ${trunk.size}")
val vTrunk = vehicle.Trunk val vTrunk = vehicle.Trunk
vTrunk.Clear() vTrunk.Clear()
trunk.foreach(entry => { trunk.foreach(entry => {
@ -1859,22 +1855,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
case None => case None =>
log.error(s"$tplayer wanted to spawn a vehicle, but there was no spawn pad associated with terminal ${msg.terminal_guid} to accept it") log.error(s"$tplayer wanted to spawn a vehicle, but there was no spawn pad associated with terminal ${msg.terminal_guid} to accept it")
} }
lastTerminalOrderFulfillment = true
case Terminal.StartProximityEffect(term) => case _ =>
val player_guid = player.GUID
val term_guid = term.GUID
StartUsingProximityUnit(term) //redundant but cautious
sendResponse(ProximityTerminalUseMessage(player_guid, term_guid, true))
localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, true))
case Terminal.StopProximityEffect(term) =>
val player_guid = player.GUID
val term_guid = term.GUID
StopUsingProximityUnit(term) //redundant but cautious
sendResponse(ProximityTerminalUseMessage(player_guid, term_guid, false))
localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, false))
case Terminal.NoDeal() =>
val order : String = if(msg == null) { val order : String = if(msg == null) {
s"order $msg" s"order $msg"
} }
@ -1883,8 +1866,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
log.warn(s"${tplayer.Name} made a request but the terminal rejected the $order") log.warn(s"${tplayer.Name} made a request but the terminal rejected the $order")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, msg.transaction_type, false)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, msg.transaction_type, false))
lastTerminalOrderFulfillment = true
} }
lastTerminalOrderFulfillment = true
} }
/** /**
@ -2866,7 +2849,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
player.Jumping = is_jumping player.Jumping = is_jumping
if(vel.isDefined && usingMedicalTerminal.isDefined) { if(vel.isDefined && usingMedicalTerminal.isDefined) {
StopUsingProximityUnit(continent.GUID(usingMedicalTerminal.get).get.asInstanceOf[ProximityTerminal]) continent.GUID(usingMedicalTerminal) match {
case Some(term : Terminal with ProximityUnit) =>
StopUsingProximityUnit(term)
case _ => ;
}
} }
accessedContainer match { accessedContainer match {
case Some(veh : Vehicle) => case Some(veh : Vehicle) =>
@ -3316,10 +3303,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
// Stop using proximity terminals if player unholsters a weapon (which should re-trigger the proximity effect and re-holster the weapon) // Stop using proximity terminals if player unholsters a weapon (which should re-trigger the proximity effect and re-holster the weapon)
if(player.VisibleSlots.contains(held_holsters)) { if(player.VisibleSlots.contains(held_holsters)) {
usingMedicalTerminal match { continent.GUID(usingMedicalTerminal) match {
case Some(term_guid) => case Some(term : Terminal with ProximityUnit) =>
StopUsingProximityUnit(continent.GUID(term_guid).get.asInstanceOf[ProximityTerminal]) StopUsingProximityUnit(term)
case None => ; case _ => ;
} }
} }
} }
@ -3764,7 +3751,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO matrix spawn point; for now, just blindly bind to show work (and hope nothing breaks) //TODO matrix spawn point; for now, just blindly bind to show work (and hope nothing breaks)
sendResponse(BindPlayerMessage(BindStatus.Bind, "", true, true, SpawnGroup.Sanctuary, 0, 0, terminal.Position)) sendResponse(BindPlayerMessage(BindStatus.Bind, "", true, true, SpawnGroup.Sanctuary, 0, 0, terminal.Position))
} }
else if(tdef.isInstanceOf[RepairRearmSiloDefinition] || tdef == GlobalDefinitions.multivehicle_rearm_terminal) { else if(tdef == GlobalDefinitions.multivehicle_rearm_terminal || tdef == GlobalDefinitions.bfr_rearm_terminal ||
tdef == GlobalDefinitions.air_rearm_terminal || tdef == GlobalDefinitions.ground_rearm_terminal) {
FindLocalVehicle match { FindLocalVehicle match {
case Some(vehicle) => case Some(vehicle) =>
sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType)) sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType))
@ -3847,12 +3835,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.info(s"ProximityTerminalUse: $msg") log.info(s"ProximityTerminalUse: $msg")
continent.GUID(object_guid) match { continent.GUID(object_guid) match {
case Some(obj : Terminal with ProximityUnit) => case Some(obj : Terminal with ProximityUnit) =>
if(usingProximityTerminal.contains(object_guid)) { HandleProximityTerminalUse(obj)
SelectProximityUnit(obj)
}
else {
StartUsingProximityUnit(obj)
}
case Some(obj) => ; case Some(obj) => ;
log.warn(s"ProximityTerminalUse: object does not have proximity effects - $obj") log.warn(s"ProximityTerminalUse: object does not have proximity effects - $obj")
case None => case None =>
@ -6011,7 +5994,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 29, 1)) avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 29, 1))
} }
PlayerActionsToCancel() PlayerActionsToCancel()
CancelAllProximityUnits()
//TODO other methods of death? //TODO other methods of death?
val pentry = PlayerSource(tplayer) val pentry = PlayerSource(tplayer)
(tplayer.History.find({p => p.isInstanceOf[PlayerSuicide]}) match { (tplayer.History.find({p => p.isInstanceOf[PlayerSuicide]}) match {
@ -6222,21 +6204,73 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
/** /**
* Start using a proximity-base service. * na
* Special note is warranted in the case of a medical terminal or an advanced medical terminal. * @param terminal na
* @param terminal the proximity-based unit
*/ */
def StartUsingProximityUnit(terminal : Terminal with ProximityUnit) : Unit = { def HandleProximityTerminalUse(terminal : Terminal with ProximityUnit) : Unit = {
val term_guid = terminal.GUID val term_guid = terminal.GUID
if(!usingProximityTerminal.contains(term_guid)) { val targets = FindProximityUnitTargetsInScope(terminal)
usingProximityTerminal += term_guid val currentTargets = terminal.Targets
targets.foreach(target => {
if(!currentTargets.contains(target)) {
StartUsingProximityUnit(terminal, target)
}
else if(targets.isEmpty) {
log.warn(s"HandleProximityTerminalUse: ${player.Name} could not find valid targets to give to proximity unit ${terminal.Definition.Name}@${term_guid.guid}")
}
})
}
/**
* na
* @param terminal na
* @return na
*/
def FindProximityUnitTargetsInScope(terminal : Terminal with ProximityUnit) : Seq[PlanetSideGameObject] = {
terminal.Definition.asInstanceOf[ProximityDefinition].TargetValidation.keySet collect {
case ProximityTarget.Player => Some(player)
case ProximityTarget.Vehicle | ProximityTarget.Aircraft => continent.GUID(player.VehicleSeated)
} collect {
case Some(a) => a
} toSeq
}
/**
* Queue a proximity-base service.
* @param terminal the proximity-based unit
* @param target the entity that is being considered for terminal operation
*/
def StartUsingProximityUnit(terminal : Terminal with ProximityUnit, target : PlanetSideGameObject) : Unit = {
val term_guid = terminal.GUID
if(player.isAlive) {
log.info(s"StartUsingProximityUnit: ${player.Name} wants to use ${terminal.Definition.Name}@${term_guid.guid} on $target")
target match {
case _ : Player =>
terminal.Actor ! CommonMessages.Use(player, Some(target))
case _ : Vehicle =>
terminal.Actor ! CommonMessages.Use(player, Some((target, vehicleService)))
case _ =>
log.error(s"StartUsingProximityUnit: can not deal with target $target")
}
terminal.Definition match { terminal.Definition match {
case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal => case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal =>
usingMedicalTerminal = Some(term_guid) usingMedicalTerminal = Some(term_guid)
case _ => case _ => ;
SetDelayedProximityUnitReset(terminal)
} }
terminal.Actor ! CommonMessages.Use(player) }
}
/**
* Determine which functionality to pursue by a generic proximity-functional unit given the target for its activity.
* @see `VehicleService:receive, ProximityUnit.Action`
* @param terminal the proximity-based unit
* @param target the object being affected by the unit
*/
def SelectProximityUnitBehavior(terminal : Terminal with ProximityUnit, target : PlanetSideGameObject) : Unit = {
target match {
case o : Player =>
HealthAndArmorTerminal(terminal, o)
case _ => ;
} }
} }
@ -6249,42 +6283,27 @@ class WorldSessionActor extends Actor with MDCContextAware {
*/ */
def StopUsingProximityUnit(terminal : Terminal with ProximityUnit) : Unit = { def StopUsingProximityUnit(terminal : Terminal with ProximityUnit) : Unit = {
val term_guid = terminal.GUID val term_guid = terminal.GUID
if(usingProximityTerminal.contains(term_guid)) { log.info(s"StopUsingProximityUnit: attempting to stop using proximity unit ${terminal.Definition.Name}@${term_guid.guid}")
usingProximityTerminal -= term_guid val targets = FindProximityUnitTargetsInScope(terminal)
ClearDelayedProximityUnitReset(term_guid) if(targets.nonEmpty) {
if(usingMedicalTerminal.contains(term_guid)) { if(usingMedicalTerminal.contains(term_guid)) {
usingMedicalTerminal = None usingMedicalTerminal = None
} }
terminal.Actor ! CommonMessages.Unuse(player) targets.foreach(target =>
terminal.Actor ! CommonMessages.Unuse(player, Some(target))
)
}
else {
log.warn(s"StopUsingProximityUnit: ${player.Name} could not find valid targets for proximity unit ${terminal.Definition.Name}@${term_guid.guid}")
} }
} }
/** /**
* For pure proximity-based units and services, a manual attempt at cutting off the functionality. *
* First, if an existing timer can be found, cancel it.
* Then, create a new timer.
* If this timer completes, a message will be sent that will attempt to disassociate from the target proximity unit.
* @param terminal the proximity-based unit
*/ */
def SetDelayedProximityUnitReset(terminal : Terminal with ProximityUnit) : Unit = { def ForgetAllProximityTerminals(term_guid : PlanetSideGUID) : Unit = {
val terminal_guid = terminal.GUID if(usingMedicalTerminal.contains(term_guid)) {
ClearDelayedProximityUnitReset(terminal_guid) usingMedicalTerminal = None
import scala.concurrent.ExecutionContext.Implicits.global
delayedProximityTerminalResets += terminal_guid ->
context.system.scheduler.scheduleOnce(3000 milliseconds, self, DelayedProximityUnitStop(terminal))
}
/**
* For pure proximity-based units and services, disable any manual attempt at cutting off the functionality.
* If an existing timer can be found, cancel it.
* @param terminal_guid the proximity-based unit
*/
def ClearDelayedProximityUnitReset(terminal_guid : PlanetSideGUID) : Unit = {
delayedProximityTerminalResets.get(terminal_guid) match {
case Some(task) =>
task.cancel
delayedProximityTerminalResets -= terminal_guid
case None => ;
} }
} }
@ -6292,37 +6311,15 @@ class WorldSessionActor extends Actor with MDCContextAware {
* Cease all current interactions with proximity-based units. * Cease all current interactions with proximity-based units.
* Pair with `PlayerActionsToCancel`, except when logging out (stopping). * Pair with `PlayerActionsToCancel`, except when logging out (stopping).
* This operations may invoke callback messages. * This operations may invoke callback messages.
* @see `postStop`<br> * @see `postStop`
* `Terminal.StopProximityEffects`
*/ */
def CancelAllProximityUnits() : Unit = { def CancelAllProximityUnits() : Unit = {
delayedProximityTerminalResets.foreach({case(term_guid, task) => continent.GUID(usingMedicalTerminal) match {
task.cancel case Some(terminal : Terminal with ProximityUnit) =>
delayedProximityTerminalResets -= term_guid FindProximityUnitTargetsInScope(terminal).foreach(target =>
}) terminal.Actor ! CommonMessages.Unuse(player, Some(target))
usingProximityTerminal.foreach(term_guid => { )
StopUsingProximityUnit(continent.GUID(term_guid).get.asInstanceOf[ProximityTerminal]) ForgetAllProximityTerminals(usingMedicalTerminal.get)
})
}
/**
* Determine which functionality to pursue, by being given a generic proximity-functional unit
* and determinig which kind of unit is being utilized.
* @param terminal the proximity-based unit
*/
def SelectProximityUnit(terminal : Terminal with ProximityUnit) : Unit = {
terminal.Definition match {
case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal =>
ProximityMedicalTerminal(terminal)
case GlobalDefinitions.crystals_health_a | GlobalDefinitions.crystals_health_b =>
SetDelayedProximityUnitReset(terminal)
ProximityHealCrystal(terminal)
case GlobalDefinitions.repair_silo =>
SetDelayedProximityUnitReset(terminal)
//TODO insert vehicle repair here; see ProximityMedicalTerminal for example
case _ => ; case _ => ;
} }
} }
@ -6332,43 +6329,27 @@ class WorldSessionActor extends Actor with MDCContextAware {
* resotre the player's health and armor points (when they need their health and armor points restored). * resotre the player's health and armor points (when they need their health and armor points restored).
* If the player is both fully healed and fully repaired, stop using the terminal. * If the player is both fully healed and fully repaired, stop using the terminal.
* @param unit the medical terminal * @param unit the medical terminal
* @param target the player being healed
*/ */
def ProximityMedicalTerminal(unit : Terminal with ProximityUnit) : Unit = { def HealthAndArmorTerminal(unit : Terminal with ProximityUnit, target : Player) : Unit = {
val healthFull : Boolean = if(player.Health < player.MaxHealth) { val medDef = unit.Definition.asInstanceOf[MedicalTerminalDefinition]
player.History(HealFromTerm(PlayerSource(player), 10, 0, unit.Definition)) val healAmount = medDef.HealAmount
HealAction(player) val healthFull : Boolean = if(healAmount != 0 && target.Health < target.MaxHealth) {
target.History(HealFromTerm(PlayerSource(target), healAmount, 0, medDef))
HealAction(target, healAmount)
} }
else { else {
true true
} }
val armorFull : Boolean = if(player.Armor < player.MaxArmor) { val repairAmount = medDef.ArmorAmount
player.History(HealFromTerm(PlayerSource(player), 0, 10, unit.Definition)) val armorFull : Boolean = if(repairAmount != 0 && target.Armor < target.MaxArmor) {
ArmorRepairAction(player) target.History(HealFromTerm(PlayerSource(target), 0, repairAmount, medDef))
ArmorRepairAction(target, repairAmount)
} }
else { else {
true true
} }
if(healthFull && armorFull) { if(healthFull && armorFull) {
log.info(s"${player.Name} is all fixed up")
StopUsingProximityUnit(unit)
}
}
/**
* When near a red cavern crystal, resotre the player's health (when they need their health restored).
* If the player is fully healed, stop using the crystal.
* @param unit the healing crystal
*/
def ProximityHealCrystal(unit : Terminal with ProximityUnit) : Unit = {
val healthFull : Boolean = if(player.Health < player.MaxHealth) {
player.History(HealFromTerm(PlayerSource(player), 10, 0, unit.Definition))
HealAction(player)
}
else {
true
}
if(healthFull) {
log.info(s"${player.Name} is all healed up")
StopUsingProximityUnit(unit) StopUsingProximityUnit(unit)
} }
} }
@ -6382,7 +6363,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
* @return whether the player can be repaired for any more health points * @return whether the player can be repaired for any more health points
*/ */
def HealAction(tplayer : Player, healValue : Int = 10) : Boolean = { def HealAction(tplayer : Player, healValue : Int = 10) : Boolean = {
log.info(s"Dispensing health to ${tplayer.Name} - <3")
val player_guid = tplayer.GUID val player_guid = tplayer.GUID
tplayer.Health = tplayer.Health + healValue tplayer.Health = tplayer.Health + healValue
sendResponse(PlanetsideAttributeMessage(player_guid, 0, tplayer.Health)) sendResponse(PlanetsideAttributeMessage(player_guid, 0, tplayer.Health))
@ -6399,7 +6379,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
* @return whether the player can be repaired for any more armor points * @return whether the player can be repaired for any more armor points
*/ */
def ArmorRepairAction(tplayer : Player, repairValue : Int = 10) : Boolean = { def ArmorRepairAction(tplayer : Player, repairValue : Int = 10) : Boolean = {
log.info(s"Dispensing armor to ${tplayer.Name} - c[=")
val player_guid = tplayer.GUID val player_guid = tplayer.GUID
tplayer.Armor = tplayer.Armor + repairValue tplayer.Armor = tplayer.Armor + repairValue
sendResponse(PlanetsideAttributeMessage(player_guid, 4, tplayer.Armor)) sendResponse(PlanetsideAttributeMessage(player_guid, 4, tplayer.Armor))
@ -7764,7 +7743,6 @@ object WorldSessionActor {
private final case class ListAccountCharacters() private final case class ListAccountCharacters()
private final case class SetCurrentAvatar(tplayer : Player) private final case class SetCurrentAvatar(tplayer : Player)
private final case class VehicleLoaded(vehicle : Vehicle) private final case class VehicleLoaded(vehicle : Vehicle)
private final case class DelayedProximityUnitStop(unit : Terminal with ProximityUnit)
private final case class UnregisterCorpseOnVehicleDisembark(corpse : Player) private final case class UnregisterCorpseOnVehicleDisembark(corpse : Player)
private final case class CheckCargoMounting(vehicle_guid : PlanetSideGUID, cargo_vehicle_guid: PlanetSideGUID, cargo_mountpoint: Int, iteration: Int) private final case class CheckCargoMounting(vehicle_guid : PlanetSideGUID, cargo_vehicle_guid: PlanetSideGUID, cargo_mountpoint: Int, iteration: Int)
private final case class CheckCargoDismount(vehicle_guid : PlanetSideGUID, cargo_vehicle_guid: PlanetSideGUID, cargo_mountpoint: Int, iteration: Int) private final case class CheckCargoDismount(vehicle_guid : PlanetSideGUID, cargo_vehicle_guid: PlanetSideGUID, cargo_mountpoint: Int, iteration: Int)