IFF/Door orientation - Building MapID/GUID changes - Ishundar full config (#244)

* Move door orientation logic from the door itself to the IFF lock, as the lock has the correct orientation in the UBR files, whereas the door does not.

* Remove ModelID from buildings (is now GUID) and change "ID" to be "MapId". A building can also be constructed with both a GUID and MapID.

* Update Maps.scala and Zones.scala to (for the moment) only have Ishundar configured with Sounours V3 playtest base ownership. Default starting zone is also moved to Ishundar for now.

* Fix oopsie with West Zaqar Tower

* Add proximity terminal positions to constructors

* Offset vehicle spawning by the correct amount from game_objects.adb.lst

* Orient players correctly when spawning at a respawn tube

* Apply a 90 degree offset to tech plant garage locks, as these are the only locks where the orientation does not match the orientation of the door

* Add missing spawn terminals, repair/rearm terminals for both ground and air.

* Additional documentation for GOAM / PAM packets
This commit is contained in:
Mazo 2019-04-04 19:32:28 +01:00 committed by Fate-JH
parent 8313ce6491
commit 3738feec12
31 changed files with 6366 additions and 2106 deletions

View file

@ -12,29 +12,6 @@ import net.psforever.types.Vector3
*/
class Door(private val ddef : DoorDefinition) extends Amenity {
private var openState : Option[Player] = None
/** a vector in the direction of the "outside" of a room;
* typically, any locking utility is on that same "outside" */
private var outwards : Vector3 = Vector3.Zero
/**
* While setting the normal rotation angle for the door (?),
* use the angular data to determine an "inside" side and an "outside" side.<br>
* <br>
* Doors are always positioned with the frame perpendicular to the ground.
* The `i` and `j` components can be excused for this reason and only the `k` component (rotation around world-up) matters.
* Due to angle-corrected North, add 90 degrees before switching to radians and negate the cosine.
* @param orient the orientation of the door
* @return the clamped orientation of the door
*/
override def Orientation_=(orient : Vector3) : Vector3 = {
val ret = super.Orientation_=(orient)
//transform angular data into unit circle components
val rang = math.toRadians(orient.z + 90)
outwards = Vector3(-math.cos(rang).toFloat, math.sin(rang).toFloat, 0)
ret
}
def Outwards : Vector3 = outwards
def isOpen : Boolean = openState.isDefined
@ -128,18 +105,16 @@ object Door {
* Instantiate and configure a `Door` object that has knowledge of both its position and outwards-facing direction.
* The assumption is that this door will be paired with an IFF Lock, thus, has conditions for opening.
* @param pos the position of the door
* @param outwards_direction a vector in the direction of the door's outside
* @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 `Door` object
*/
def Constructor(pos : Vector3, outwards_direction : Vector3)(id : Int, context : ActorContext) : Door = {
def Constructor(pos : Vector3)(id : Int, context : ActorContext) : Door = {
import akka.actor.Props
import net.psforever.objects.GlobalDefinitions
val obj = Door(GlobalDefinitions.door)
obj.Position = pos
obj.Orientation = outwards_direction
obj.Actor = context.actorOf(Props(classOf[DoorControl], obj), s"${GlobalDefinitions.door.Name}_$id")
obj
}

View file

@ -4,6 +4,7 @@ package net.psforever.objects.serverobject.locks
import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.packet.game.TriggeredSound
import net.psforever.types.Vector3
/**
* A structure-owned server object that is a "door lock."<br>
@ -19,6 +20,30 @@ class IFFLock(private val idef : IFFLockDefinition) extends Amenity with Hackabl
HackSound = TriggeredSound.HackDoor
HackEffectDuration = Array(60, 180, 300, 360)
HackDuration = Array(5, 3, 1, 1)
/** a vector in the direction of the "outside" of a room;
* typically, any locking utility is on that same "outside" */
private var outwards : Vector3 = Vector3.Zero
/**
* While setting the normal rotation angle for the IFF lock for a door (?),
* use the angular data to determine an "inside" side and an "outside" side.<br>
* <br>
* Doors are always positioned with the frame perpendicular to the ground.
* The `i` and `j` components can be excused for this reason and only the `k` component (rotation around world-up) matters.
* Due to angle-corrected North, add 90 degrees before switching to radians and negate the cosine.
* @param orient the orientation of the door
* @return the clamped orientation of the door
*/
override def Orientation_=(orient : Vector3) : Vector3 = {
val ret = super.Orientation_=(orient)
//transform angular data into unit circle components
val rang = math.toRadians(orient.z + 90)
outwards = Vector3(-math.cos(rang).toFloat, math.sin(rang).toFloat, 0)
ret
}
def Outwards : Vector3 = outwards
}
object IFFLock {
@ -33,15 +58,20 @@ object IFFLock {
import akka.actor.ActorContext
/**
* Instantiate an configure a `IFFLock` object
* @param id the unique id that will be assigned to this entity
*
* @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
* @param pos the position of the IFF lock
* @param outwards_direction a vector used to determine which direction is inside/outside for the linked door
* @return the `IFFLock` object
*/
def Constructor(id : Int, context : ActorContext) : IFFLock = {
def Constructor(pos: Vector3, outwards_direction : Vector3)(id : Int, context : ActorContext) : IFFLock = {
import akka.actor.Props
import net.psforever.objects.GlobalDefinitions
val obj = IFFLock(GlobalDefinitions.lock_external)
obj.Position = pos
obj.Orientation = outwards_direction
obj.Actor = context.actorOf(Props(classOf[IFFLockControl], obj), s"${GlobalDefinitions.lock_external.Name}_$id")
obj
}

View file

@ -43,7 +43,7 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
case ResourceSilo.LowNtuWarning(enabled: Boolean) =>
resourceSilo.LowNtuWarningOn = enabled
log.trace(s"LowNtuWarning: Silo ${resourceSilo.GUID} low ntu warning set to $enabled")
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(PlanetSideGUID(resourceSilo.Owner.asInstanceOf[Building].ModelId), 47, if(resourceSilo.LowNtuWarningOn) 1 else 0))
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.Owner.asInstanceOf[Building].GUID, 47, if(resourceSilo.LowNtuWarningOn) 1 else 0))
case ResourceSilo.UpdateChargeLevel(amount: Int) =>
val siloChargeBeforeChange = resourceSilo.ChargeLevel
@ -81,7 +81,7 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
} else if (siloChargeBeforeChange == 0 && resourceSilo.ChargeLevel > 0) {
// Power restored. Reactor Online. Sensors Online. Weapons Online. All systems nominal.
//todo: Check generator is online before starting up
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(PlanetSideGUID(resourceSilo.Owner.asInstanceOf[Building].ModelId), 48, 0))
avatarService ! AvatarServiceMessage(resourceSilo.Owner.asInstanceOf[Building].Zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.Owner.asInstanceOf[Building].GUID, 48, 0))
}
case _ => ;
}

View file

@ -8,17 +8,16 @@ import net.psforever.objects.zones.Zone
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{PlanetSideEmpire, Vector3}
class Building(private val mapId : Int, private val zone : Zone, private val buildingType : StructureType.Value) extends PlanetSideServerObject {
class Building(private val building_guid : Int, private val map_id : Int, private val zone : Zone, private val buildingType : StructureType.Value) extends PlanetSideServerObject {
/**
* The mapId is the identifier number used in BuildingInfoUpdateMessage.
* The modelId is the identifier number used in SetEmpireMessage / Facility hacking / PlanetSideAttributeMessage.
* The map_id is the identifier number used in BuildingInfoUpdateMessage. This is the index that the building appears in the MPO file starting from index 1
* The GUID is the identifier number used in SetEmpireMessage / Facility hacking / PlanetSideAttributeMessage.
*/
private var modelId : Option[Int] = None
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
private var amenities : List[Amenity] = List.empty
GUID = PlanetSideGUID(0)
GUID = PlanetSideGUID(building_guid)
def Id : Int = mapId
def MapId : Int = map_id
def Faction : PlanetSideEmpire.Value = faction
@ -37,15 +36,6 @@ class Building(private val mapId : Int, private val zone : Zone, private val bui
def Zone : Zone = zone
def ModelId : Int = modelId.getOrElse(Id)
def ModelId_=(id : Int) : Int = ModelId_=(Some(id))
def ModelId_=(id : Option[Int]) : Int = {
modelId = id
ModelId
}
def BuildingType : StructureType.Value = buildingType
override def Continent : String = zone.Id
@ -56,29 +46,29 @@ class Building(private val mapId : Int, private val zone : Zone, private val bui
}
object Building {
final val NoBuilding : Building = new Building(0, Zone.Nowhere, StructureType.Platform) {
final val NoBuilding : Building = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Platform) {
override def Faction_=(faction : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
override def Amenities_=(obj : Amenity) : List[Amenity] = Nil
}
final val BuildingDefinition : ObjectDefinition = new ObjectDefinition(0) { Name = "building" }
def apply(id : Int, zone : Zone, buildingType : StructureType.Value) : Building = {
new Building(id, zone, buildingType)
def apply(guid : Int, map_id : Int, zone : Zone, buildingType : StructureType.Value) : Building = {
new Building(guid, map_id, zone, buildingType)
}
def Structure(buildingType : StructureType.Value, location : Vector3)(id : Int, zone : Zone, context : ActorContext) : Building = {
def Structure(buildingType : StructureType.Value, location : Vector3)(guid : Int, map_id : Int, zone : Zone, context : ActorContext) : Building = {
import akka.actor.Props
val obj = new Building(id, zone, buildingType)
val obj = new Building(guid, map_id, zone, buildingType)
obj.Position = location
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$id-$buildingType-building")
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-$buildingType-building")
obj
}
def Structure(buildingType : StructureType.Value)(id : Int, zone : Zone, context : ActorContext) : Building = {
def Structure(buildingType : StructureType.Value)(guid: Int, map_id : Int, zone : Zone, context : ActorContext) : Building = {
import akka.actor.Props
val obj = new Building(id, zone, buildingType)
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$id-$buildingType-building")
val obj = new Building(guid, map_id, zone, buildingType)
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-$buildingType-building")
obj
}

View file

@ -29,7 +29,7 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
private[this] val log = org.log4s.getLogger
override def preStart = {
log.info(s"Starting BuildingControl for ${building.GUID} / ${building.ModelId}")
log.info(s"Starting BuildingControl for ${building.GUID} / ${building.MapId}")
ServiceManager.serviceManager ! Lookup("galaxy")
ServiceManager.serviceManager ! Lookup("local")
}
@ -37,10 +37,10 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
def receive : Receive = checkBehavior.orElse {
case ServiceManager.LookupResult("galaxy", endpoint) =>
galaxyService = endpoint
log.info("BuildingControl: Building " + building.ModelId + " Got galaxy service " + endpoint)
log.info("BuildingControl: Building " + building.GUID + " Got galaxy service " + endpoint)
case ServiceManager.LookupResult("local", endpoint) =>
localService = endpoint
log.info("BuildingControl: Building " + building.ModelId + " Got local service " + endpoint)
log.info("BuildingControl: Building " + building.GUID + " Got local service " + endpoint)
case FactionAffinity.ConvertFactionAffinity(faction) =>
val originalAffinity = building.Faction
if(originalAffinity != (building.Faction = faction)) {
@ -48,7 +48,7 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
}
sender ! FactionAffinity.AssertFactionAffinity(building, faction)
case Building.SendMapUpdate(all_clients: Boolean) =>
log.info(s"Sending BuildingInfoUpdateMessage update. Zone: ${building.Zone.Number} - Building: ${building.ModelId}")
log.info(s"Sending BuildingInfoUpdateMessage update. Zone: ${building.Zone.Number} - Building: ${building.GUID} / MapId: ${building.MapId}")
var ntuLevel = 0
var is_hacked = false
var hack_time_remaining_ms = 0L;
@ -80,7 +80,7 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
val msg = BuildingInfoUpdateMessage(
continent_id = building.Zone.Number, //Zone
building_id = building.Id, //Facility
building_map_id = building.MapId, //Facility
ntu_level = ntuLevel,
is_hacked,
hacked_by_faction,

View file

@ -11,9 +11,9 @@ import net.psforever.objects.zones.Zone
* @see `Building`
* @param constructor a curried function that eventually constructs a `Building` object
*/
class FoundationBuilder(private val constructor : (Int, Zone, ActorContext)=>Building) {
def Build(id : Int, zone : Zone)(implicit context : ActorContext = null) : Building = {
val obj : Building = constructor(id, zone, context)
class FoundationBuilder(private val constructor : (Int, Int, Zone, ActorContext)=>Building) {
def Build(guid : Int, map_id: Int, zone : Zone)(implicit context : ActorContext = null) : Building = {
val obj : Building = constructor(guid, map_id, zone, context)
obj
}
}
@ -24,7 +24,7 @@ object FoundationBuilder {
* @param constructor a curried function that eventually constructs a `Building` object
* @return a `FoundationBuilder` object
*/
def apply(constructor : (Int, Zone, ActorContext)=>Building) : FoundationBuilder = {
def apply(constructor : (Int, Int, Zone, ActorContext)=>Building) : FoundationBuilder = {
new FoundationBuilder(constructor)
}
}

View file

@ -4,19 +4,19 @@ package net.psforever.objects.serverobject.structures
import akka.actor.ActorContext
import net.psforever.objects.zones.Zone
class WarpGate(id : Int, zone : Zone) extends Building(id, zone, StructureType.WarpGate) {
class WarpGate(building_guid : Int, map_id : Int, zone : Zone) extends Building(building_guid, map_id, zone, StructureType.WarpGate) {
//TODO stuff later
}
object WarpGate {
def apply(id : Int, zone : Zone) : WarpGate = {
new WarpGate(id, zone)
def apply(guid : Int, map_id : Int, zone : Zone) : WarpGate = {
new WarpGate(guid, map_id, zone)
}
def Structure(id : Int, zone : Zone, context : ActorContext) : WarpGate = {
def Structure(guid : Int, map_id : Int, zone : Zone, context : ActorContext) : WarpGate = {
import akka.actor.Props
val obj = new WarpGate(id, zone)
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$id-gate")
val obj = new WarpGate(guid, map_id, zone)
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-gate")
obj
}
}

View file

@ -312,6 +312,10 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
buildings.get(id)
}
def BuildingByMapId(map_id : Int) : Building = {
buildings.filter(x => x._2.MapId == map_id).head._2
}
private def BuildLocalObjects(implicit context : ActorContext, guid : NumberPoolHub) : Unit = {
Map.LocalObjects.foreach({ builderObject => builderObject.Build })
}
@ -350,7 +354,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
private def MakeBuildings(implicit context : ActorContext) : PairMap[Int, Building] = {
val buildingList = Map.LocalBuildings
buildings = buildingList.map({case(building_id, constructor) => building_id -> constructor.Build(building_id, this) })
buildings = buildingList.map({case((building_guid, map_id), constructor) => building_guid -> constructor.Build(building_guid, map_id, this) })
buildings
}
@ -388,10 +392,10 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
def SpawnGroups() : Map[Building, List[SpawnTube]] = spawnGroups
def SpawnGroups(building : Building) : List[SpawnTube] = SpawnGroups(building.Id)
def SpawnGroups(building : Building) : List[SpawnTube] = SpawnGroups(building.MapId)
def SpawnGroups(buildingId : Int) : List[SpawnTube] = {
spawnGroups.find({ case((building, _)) => building.Id == buildingId }) match {
spawnGroups.find({ case((building, _)) => building.MapId == buildingId }) match {
case Some((_, list)) =>
list
case None =>

View file

@ -31,7 +31,7 @@ class ZoneMap(private val name : String) {
private var linkTerminalInterface : Map[Int, Int] = Map()
private var linkDoorLock : Map[Int, Int] = Map()
private var linkObjectBase : Map[Int, Int] = Map()
private var buildings : Map[Int, FoundationBuilder] = Map()
private var buildings : Map[(Int, Int), FoundationBuilder] = Map()
def Name : String = name
@ -56,11 +56,11 @@ class ZoneMap(private val name : String) {
localObjects.size
}
def LocalBuildings : Map[Int, FoundationBuilder] = buildings
def LocalBuildings : Map[(Int, Int), FoundationBuilder] = buildings
def LocalBuilding(building_id : Int, constructor : FoundationBuilder) : Int = {
if(building_id > 0) {
buildings = buildings ++ Map(building_id -> constructor)
def LocalBuilding(building_guid : Int, map_id : Int, constructor : FoundationBuilder) : Int = {
if(building_guid > 0) {
buildings = buildings ++ Map((building_guid, map_id) -> constructor)
}
buildings.size
}

View file

@ -88,7 +88,7 @@ final case class Additional3(unk1 : Boolean,
* 128 - Pain Module<br>
* `
* @param continent_id the continent (zone)
* @param building_id the building
* @param building_map_id the map id of this building from the MPO files
* @param ntu_level if the building has a silo, the amount of NTU in that silo;
* NTU is reported in multiples of 10%;
* valid for 0 (0%) to 10 (100%)
@ -118,7 +118,7 @@ final case class Additional3(unk1 : Boolean,
* @param boost_generator_pain if the building has a generator, the (boosted) strength of its enemy pain field
*/
final case class BuildingInfoUpdateMessage(continent_id : Int,
building_id : Int,
building_map_id : Int,
ntu_level : Int,
is_hacked : Boolean,
empire_hack : PlanetSideEmpire.Value,

View file

@ -12,6 +12,12 @@ import shapeless.{::, HNil}
* (Write more some other time.)
* @param object_guid the target object
* @param code the action code
* 44, 45, 46, 47 - Deploy capital base shield pole with animation and broadcasts "The capitol force dome at X has been activated"
* 48, 49, 50, 51 - Stow capital base shield pole with animation and broadcasts "The capitol force dome at X has been deactivated"
* 52, 53, 54, 55 - Deploy capital base shield pole (instantly, unless still in the middle of the stow animation)
* 60, 61, 62, 63 - Displays "This facility's generator is under attack!"
* 64, 65, 66, 67 - Displays "Generator has Overloaded! Evacuate Generator Room Immediately!"
* 68, 69, 70, 71 - Displays "This facility's generator is back on line"
* 96, 97, 98, 99 - Makes the vehicle bounce slightly. Have seen this in packet captures after taking a vehicle through a warpgate
* 200, 201, 202, 203 - For aircraft - client shows "THe bailing mechanism failed! To fix the mechanism, land and repair the vehicle!"
* 224 - Sets vehicle or player to be black ops

View file

@ -115,6 +115,7 @@ import scodec.codecs._
* `36 - CR. Value is the CR`<br>
* `43 - Info on avatar name : 0 = Nothing, 1 = "(LD)" message`<br>
* `45 - NTU charge bar 0-10, 5 = 50% full. Seems to apply to both ANT and NTU Silo (possibly siphons?)`<br>
* `46 - Sends "Generator damage is at a critical level!" message`
* `47 - Sets base NTU level to CRITICAL. MUST use base modelId not base GUID`<br>
* `48 - Set to 1 to send base power loss message & turns on red warning lights throughout base. MUST use base modelId not base GUID`<br>
* `49 - Vehicle texture effects state? (>0 turns on ANT panel glow or ntu silo panel glow + orbs) (bit?)`<br>

View file

@ -183,10 +183,10 @@ class LocalService extends Actor {
}
if(ntuLevel > 0) {
log.info(s"Setting base ${building.ModelId} as owned by $hackedByFaction")
log.info(s"Setting base ${building.GUID} / MapId: ${building.MapId} as owned by $hackedByFaction")
building.Faction = hackedByFaction
self ! LocalServiceMessage(zone.Id, LocalAction.SetEmpire(PlanetSideGUID(building.ModelId), hackedByFaction))
self ! LocalServiceMessage(zone.Id, LocalAction.SetEmpire(building.GUID, hackedByFaction))
} else {
log.info("Base hack completed, but base was out of NTU.")
}
@ -194,7 +194,7 @@ class LocalService extends Actor {
// Reset CC back to normal operation
self ! LocalServiceMessage(zone.Id, LocalAction.HackCaptureTerminal(PlanetSideGUID(-1), zone, terminal, 0, 8L, isResecured = true))
//todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. The attribute above is a workaround
self ! HackClearActor.ClearTheHack(PlanetSideGUID(building.ModelId), zone.Id, 3212836864L, 8L)
self ! HackClearActor.ClearTheHack(building.GUID, zone.Id, 3212836864L, 8L)
case Success(_) =>
log.warn("Got success from InterstellarCluster.GetWorld but didn't know how to handle it")

View file

@ -89,7 +89,7 @@ class HackCaptureActor extends Actor {
val hackEntry = hackedObjects.reduceLeft(minTimeLeft)
val short_timeout : FiniteDuration = math.max(1, hackEntry.duration.toNanos - (System.nanoTime - hackEntry.hack_timestamp)) nanoseconds
log.trace(s"Still items left in hacked objects list. Checking again in ${short_timeout}")
log.trace(s"Still items left in hacked objects list. Checking again in ${short_timeout.toSeconds} seconds")
import scala.concurrent.ExecutionContext.Implicits.global
clearTrigger = context.system.scheduler.scheduleOnce(short_timeout, self, HackCaptureActor.ProcessCompleteHacks())
}

View file

@ -68,7 +68,7 @@ class HackClearActor() extends Actor {
val (unhackObjects, stillHackedObjects) = PartitionEntries(hackedObjects, now)
val short_timeout : FiniteDuration = math.max(1, stillHackedObjects.head.duration - (now - stillHackedObjects.head.time)) nanoseconds
log.warn(s"Still items left in hacked objects list. Checking again in ${short_timeout}")
log.warn(s"Still items left in hacked objects list. Checking again in ${short_timeout.toSeconds} seconds")
import scala.concurrent.ExecutionContext.Implicits.global
clearTrigger = context.system.scheduler.scheduleOnce(short_timeout, self, HackClearActor.TryClearHacks())
}

View file

@ -30,7 +30,7 @@ class AmenityTest extends Specification {
"can be owned by a building" in {
val ao = new AmenityObject()
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
ao.Owner = bldg
ao.Owner mustEqual bldg
@ -54,7 +54,7 @@ class AmenityTest extends Specification {
"confer faction allegiance through ownership" in {
//see FactionAffinityTest
val ao = new AmenityObject()
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
ao.Owner = bldg
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
ao.Faction mustEqual PlanetSideEmpire.NEUTRAL
@ -69,8 +69,8 @@ class AmenityTest extends Specification {
class BuildingTest extends Specification {
"Building" should {
"construct" in {
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
bldg.Id mustEqual 10
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
bldg.MapId mustEqual 10
bldg.Actor mustEqual ActorRef.noSender
bldg.Amenities mustEqual Nil
bldg.Zone mustEqual Zone.Nowhere
@ -78,7 +78,7 @@ class BuildingTest extends Specification {
}
"change faction affinity" in {
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
bldg.Faction = PlanetSideEmpire.TR
@ -86,7 +86,7 @@ class BuildingTest extends Specification {
}
"keep track of amenities" in {
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
val door1 = Door(GlobalDefinitions.door)
val door2 = Door(GlobalDefinitions.door)
@ -104,8 +104,8 @@ class BuildingTest extends Specification {
class WarpGateTest extends Specification {
"WarpGate" should {
"construct" in {
val bldg = WarpGate(10, Zone.Nowhere)
bldg.Id mustEqual 10
val bldg = WarpGate(0, 10, Zone.Nowhere)
bldg.MapId mustEqual 10
bldg.Actor mustEqual ActorRef.noSender
bldg.Amenities mustEqual Nil
bldg.Zone mustEqual Zone.Nowhere
@ -117,7 +117,7 @@ class WarpGateTest extends Specification {
class BuildingControl1Test extends ActorTest {
"Building Control" should {
"construct" in {
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
assert(bldg.Actor != ActorRef.noSender)
}
@ -126,7 +126,7 @@ class BuildingControl1Test extends ActorTest {
class BuildingControl2Test extends ActorTest {
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService], "galaxy")
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
bldg.Faction = PlanetSideEmpire.TR
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
bldg.Actor ! "startup"
@ -148,7 +148,7 @@ class BuildingControl2Test extends ActorTest {
class BuildingControl3Test extends ActorTest {
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService], "galaxy")
val bldg = Building(10, Zone.Nowhere, StructureType.Building)
val bldg = Building(0, 10, Zone.Nowhere, StructureType.Building)
bldg.Faction = PlanetSideEmpire.TR
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
val door1 = Door(GlobalDefinitions.door)

View file

@ -43,7 +43,7 @@ class DoorTest extends Specification {
}
"be opened and closed (2; toggle)" in {
val msg = UseItemMessage(PlanetSideGUID(6585), PlanetSideGUID(0), PlanetSideGUID(372), 4294967295L, false, Vector3(5.0f,0.0f,0.0f), Vector3(0.0f,0.0f,0.0f), 11, 25, 0, 364)
val msg = UseItemMessage(PlanetSideGUID(6585), PlanetSideGUID(0), PlanetSideGUID(372), 4294967295L, false, Vector3(5.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), 11, 25, 0, 364)
val door = Door(GlobalDefinitions.door)
door.Open mustEqual None
door.Use(player, msg)
@ -51,27 +51,6 @@ class DoorTest extends Specification {
door.Use(player, msg)
door.Open mustEqual None
}
"keep track of its orientation as a North-corrected vector" in {
val ulp = math.ulp(1)
val door = Door(GlobalDefinitions.door)
door.Orientation = Vector3(0, 0, 0) //face North
door.Outwards.x < ulp mustEqual true
door.Outwards.y mustEqual 1
door.Orientation = Vector3(0, 0, 90) //face East
door.Outwards.x mustEqual 1
door.Outwards.y < ulp mustEqual true
door.Orientation = Vector3(0, 0, 180) //face South
door.Outwards.x < ulp mustEqual true
door.Outwards.y mustEqual -1
door.Orientation = Vector3(0, 0, 270) //face West
door.Outwards.x mustEqual -1
door.Outwards.y < ulp mustEqual true
}
}
}
@ -122,7 +101,7 @@ object DoorControlTest {
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, Door) = {
val door = Door(GlobalDefinitions.door)
door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door")
door.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
door.Owner = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
door.Owner.Faction = faction
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), door)
}

View file

@ -102,7 +102,7 @@ class FacilityTurretControl2Test extends ActorTest {
val obj = FacilityTurret(GlobalDefinitions.manned_turret)
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[FacilityTurretControl], obj), "turret-control")
val bldg = Building(0, Zone.Nowhere, StructureType.Building)
val bldg = Building(guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
bldg.Amenities = obj
bldg.Faction = PlanetSideEmpire.TR
@ -129,7 +129,7 @@ class FacilityTurretControl3Test extends ActorTest {
val obj = FacilityTurret(GlobalDefinitions.manned_turret)
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[FacilityTurretControl], obj), "turret-control")
val bldg = Building(0, Zone.Nowhere, StructureType.Building)
val bldg = Building(guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
bldg.Amenities = obj
"FacilityTurretControl" should {
@ -157,7 +157,7 @@ class FacilityTurretControl4Test extends ActorTest {
val obj = FacilityTurret(objDef)
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[FacilityTurretControl], obj), "turret-control")
val bldg = Building(0, Zone.Nowhere, StructureType.Building)
val bldg = Building(guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
bldg.Amenities = obj
"FacilityTurretControl" should {

View file

@ -43,7 +43,7 @@ class FactionAffinityTest extends Specification {
"inherits affinity from owner 2" in {
val obj = new Door(GlobalDefinitions.door)
val bldg = new Building(1, Zone.Nowhere, StructureType.Building)
val bldg = new Building(building_guid = 0, map_id = 1, Zone.Nowhere, StructureType.Building)
obj.Owner = bldg
obj.Faction mustEqual PlanetSideEmpire.NEUTRAL

View file

@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.locks.{IFFLock, IFFLockControl}
import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
import org.specs2.mutable.Specification
class IFFLockTest extends Specification {
@ -20,6 +20,27 @@ class IFFLockTest extends Specification {
}
//TODO internal hacking logic will be re-written later
"keep track of its orientation as a North-corrected vector" in {
val ulp = math.ulp(1)
val lock = IFFLock(GlobalDefinitions.lock_external)
lock.Orientation = Vector3(0, 0, 0) //face North
lock.Outwards.x < ulp mustEqual true
lock.Outwards.y mustEqual 1
lock.Orientation = Vector3(0, 0, 90) //face East
lock.Outwards.x mustEqual 1
lock.Outwards.y < ulp mustEqual true
lock.Orientation = Vector3(0, 0, 180) //face South
lock.Outwards.x < ulp mustEqual true
lock.Outwards.y mustEqual -1
lock.Orientation = Vector3(0, 0, 270) //face West
lock.Outwards.x mustEqual -1
lock.Outwards.y < ulp mustEqual true
}
}
}
@ -68,7 +89,7 @@ object IFFLockControlTest {
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, IFFLock) = {
val lock = IFFLock(GlobalDefinitions.lock_external)
lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control")
lock.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
lock.Owner = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
lock.Owner.Faction = faction
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), lock)
}

View file

@ -111,9 +111,7 @@ class ResourceSiloControlNtuWarningTest extends ActorTest {
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
obj.Actor ! "startup"
obj.Owner = new Building(0, Zone.Nowhere, StructureType.Building) {
ModelId = 6
}
obj.Owner = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building)
"Resource silo" should {
"announce high ntu" in {
@ -146,9 +144,7 @@ class ResourceSiloControlUpdate1Test extends ActorTest {
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
obj.Actor ! "startup"
val bldg = new Building(0, Zone.Nowhere, StructureType.Building) {
ModelId = 6
}
val bldg = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building)
val probe2 = TestProbe()
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
obj.Owner = bldg
@ -215,9 +211,7 @@ class ResourceSiloControlUpdate2Test extends ActorTest {
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
obj.Actor ! "startup"
val bldg = new Building(0, Zone.Nowhere, StructureType.Building) {
ModelId = 6
}
val bldg = new Building(building_guid = 6, map_id = 0, Zone.Nowhere, StructureType.Building)
val probe2 = TestProbe()
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
obj.Owner = bldg
@ -276,9 +270,7 @@ class ResourceSiloControlNoUpdateTest extends ActorTest {
obj.GUID = PlanetSideGUID(1)
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
obj.Actor ! "startup"
val bldg = new Building(0, Zone.Nowhere, StructureType.Building) {
ModelId = 6
}
val bldg = new Building(building_guid = 6, map_id = 6, Zone.Nowhere, StructureType.Building)
val probe2 = TestProbe()
bldg.Actor = system.actorOf(Props(classOf[ResourceSiloTest.ProbedBuildingControl], probe2), "test-bldg")
obj.Owner = bldg
@ -298,7 +290,7 @@ class ResourceSiloControlNoUpdateTest extends ActorTest {
expectNoMsg(500 milliseconds)
probe1.expectNoMsg(500 milliseconds)
probe2.expectNoMsg(500 milliseconds)
assert(obj.ChargeLevel == 300)
assert(obj.ChargeLevel == 299 || obj.ChargeLevel == 300) // Just in case the capacitor level drops while waiting for the message check 299 & 300
assert(obj.CapacitorDisplay == 3)
assert(obj.LowNtuWarningOn == false)
}

View file

@ -16,13 +16,13 @@ import scala.concurrent.duration.Duration
class BuildingBuilderTest extends ActorTest {
"Building object" should {
"build" in {
val structure : (Int,Zone,ActorContext)=>Building = Building.Structure(StructureType.Building)
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, 10, Zone.Nowhere), "building")
val structure : (Int,Int,Zone,ActorContext)=>Building = Building.Structure(StructureType.Building)
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, 10, 10, Zone.Nowhere), "building")
actor ! "!"
val reply = receiveOne(Duration.create(1000, "ms"))
assert(reply.isInstanceOf[Building])
assert(reply.asInstanceOf[Building].Id == 10)
assert(reply.asInstanceOf[Building].MapId == 10)
assert(reply.asInstanceOf[Building].Zone == Zone.Nowhere)
}
}
@ -31,13 +31,13 @@ class BuildingBuilderTest extends ActorTest {
class WarpGateBuilderTest extends ActorTest {
"WarpGate object" should {
"build" in {
val structure : (Int,Zone,ActorContext)=>Building = WarpGate.Structure
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, 10, Zone.Nowhere), "wgate")
val structure : (Int,Int,Zone,ActorContext)=>Building = WarpGate.Structure
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, 10, 10, Zone.Nowhere), "wgate")
actor ! "!"
val reply = receiveOne(Duration.create(1000, "ms"))
assert(reply.isInstanceOf[Building])
assert(reply.asInstanceOf[Building].Id == 10)
assert(reply.asInstanceOf[Building].MapId == 10)
assert(reply.asInstanceOf[Building].Zone == Zone.Nowhere)
}
}
@ -65,14 +65,12 @@ class DoorObjectBuilderTest2 extends ActorTest {
"Door object" should {
"build" in {
val hub = ServerObjectBuilderTest.NumberPoolHub
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, Door.Constructor(Vector3(1, 2, 3), Vector3(90, 180, 45))), hub), "door")
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, Door.Constructor(Vector3(1, 2, 3))), hub), "door")
actor ! "!"
val reply = receiveOne(Duration.create(1000, "ms"))
assert(reply.isInstanceOf[Door])
assert(reply.asInstanceOf[Door].Position == Vector3(1, 2, 3))
assert(reply.asInstanceOf[Door].Orientation == Vector3(90, 180, 45))
assert(reply.asInstanceOf[Door].Outwards == Vector3(0.70710677f, 0.70710677f, 0f))
assert(reply.asInstanceOf[Door].HasGUID)
assert(reply.asInstanceOf[Door].GUID == PlanetSideGUID(1))
assert(reply == hub(1).get)
@ -85,7 +83,7 @@ class IFFLockObjectBuilderTest extends ActorTest {
"IFFLock object" should {
"build" in {
val hub = ServerObjectBuilderTest.NumberPoolHub
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, IFFLock.Constructor), hub), "lock")
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, IFFLock.Constructor(Vector3(0f, 0f, 0f), Vector3(0f, 0f, 0f))), hub), "lock")
actor ! "!"
val reply = receiveOne(Duration.create(1000, "ms"))
@ -279,10 +277,10 @@ object ServerObjectBuilderTest {
}
}
class BuildingTestActor(structure_con : (Int,Zone,ActorContext)=>Building, building_id : Int, zone : Zone) extends Actor {
class BuildingTestActor(structure_con : (Int,Int,Zone,ActorContext)=>Building, building_guid : Int, map_id : Int, zone : Zone) extends Actor {
def receive : Receive = {
case _ =>
sender ! FoundationBuilder(structure_con).Build(building_id, zone)(context)
sender ! FoundationBuilder(structure_con).Build(building_guid, map_id, zone)(context)
}
}
}

View file

@ -339,7 +339,7 @@ object VehicleSpawnPadControlTest {
val pad = VehicleSpawnPad(GlobalDefinitions.spawn_pad)
pad.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], pad), s"test-pad-${System.nanoTime()}")
pad.Owner = new Building(0, zone, StructureType.Building)
pad.Owner = new Building(building_guid = 0, map_id = 0, zone, StructureType.Building)
pad.Owner.Faction = faction
val player = Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute))
player.GUID = PlanetSideGUID(10)

View file

@ -22,7 +22,7 @@ import org.specs2.mutable.Specification
import scala.concurrent.duration._
class ZoneTest extends Specification {
def test(a: Int, b : Zone, c : ActorContext) : Building = { Building.NoBuilding }
def test(a: Int, b: Int, c : Zone, d : ActorContext) : Building = { Building.NoBuilding }
"ZoneMap" should {
"construct" in {
@ -33,11 +33,11 @@ class ZoneTest extends Specification {
"references bases by a positive building id (defaults to 0)" in {
val map = new ZoneMap("map13")
map.LocalBuildings mustEqual Map.empty
map.LocalBuilding(10, FoundationBuilder(test))
map.LocalBuildings.keySet.contains(10) mustEqual true
map.LocalBuilding(-1, FoundationBuilder(test))
map.LocalBuildings.keySet.contains(10) mustEqual true
map.LocalBuildings.keySet.contains(-1) mustEqual false
map.LocalBuilding(building_guid = 10, map_id = 0, FoundationBuilder(test))
map.LocalBuildings.keySet.contains((10, 0)) mustEqual true
map.LocalBuilding(building_guid = -1, map_id = 0, FoundationBuilder(test))
map.LocalBuildings.keySet.contains((0, 0)) mustEqual true
map.LocalBuildings.keySet.contains((-1, 0)) mustEqual false
}
"associates objects to bases (doesn't check numbers)" in {
@ -87,7 +87,7 @@ class ZoneTest extends Specification {
}
val map13 = new ZoneMap("map13")
map13.LocalBuilding(10, FoundationBuilder(test))
map13.LocalBuilding(building_guid = 0, map_id = 10, FoundationBuilder(test))
class TestObject extends IdentifiableEntity
"Zone" should {
@ -172,7 +172,7 @@ class ZoneActorTest extends ActorTest {
"set up spawn groups based on buildings" in {
val map6 = new ZoneMap("map6") {
LocalBuilding(1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalBuilding(building_guid = 1, map_id = 1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalObject(1, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
LocalObject(2, Terminal.Constructor(GlobalDefinitions.dropship_vehicle_terminal))
LocalObject(3, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
@ -180,11 +180,11 @@ class ZoneActorTest extends ActorTest {
ObjectToBuilding(2, 1)
ObjectToBuilding(3, 1)
LocalBuilding(2, FoundationBuilder(Building.Structure(StructureType.Building)))
LocalBuilding(building_guid = 2, map_id = 2, FoundationBuilder(Building.Structure(StructureType.Building)))
LocalObject(7, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
ObjectToBuilding(7, 2)
LocalBuilding(3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalBuilding(building_guid = 3, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalObject(4, Terminal.Constructor(GlobalDefinitions.dropship_vehicle_terminal))
LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
LocalObject(6, Terminal.Constructor(GlobalDefinitions.dropship_vehicle_terminal))
@ -200,7 +200,7 @@ class ZoneActorTest extends ActorTest {
val groups = zone.SpawnGroups()
assert(groups.size == 2)
zone.SpawnGroups().foreach({ case(building, tubes) =>
if(building.Id == 1) {
if(building.MapId == 1) {
val building1 = zone.SpawnGroups(building)
assert(tubes.length == 2)
assert(tubes.head == building1.head)
@ -208,7 +208,7 @@ class ZoneActorTest extends ActorTest {
assert(tubes(1) == building1(1))
assert(tubes(1).GUID == PlanetSideGUID(3))
}
else if(building.Id == 3) {
else if(building.MapId == 3) {
val building2 = zone.SpawnGroups(building)
assert(tubes.length == 1)
assert(tubes.head == building2.head)
@ -222,11 +222,11 @@ class ZoneActorTest extends ActorTest {
"select spawn points based on the position of the player in reference to buildings" in {
val map6 = new ZoneMap("map6") {
LocalBuilding(1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalBuilding(building_guid = 1, map_id = 1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalObject(1, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
ObjectToBuilding(1, 1)
LocalBuilding(3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(4,4,4))))
LocalBuilding(building_guid = 3, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(4,4,4))))
LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
ObjectToBuilding(5, 3)
}
@ -255,9 +255,9 @@ class ZoneActorTest extends ActorTest {
"will report if no spawn points have been found in a zone" in {
val map6 = new ZoneMap("map6") {
LocalBuilding(1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalBuilding(building_guid = 1, map_id = 1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
LocalBuilding(3, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(4,4,4))))
LocalBuilding(building_guid = 3, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Tower, Vector3(4,4,4))))
LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero))
ObjectToBuilding(5, 3)
}

View file

@ -161,7 +161,7 @@ object ImplantTerminalMechTest {
val terminal = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
terminal.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], terminal), "mech")
terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
terminal.Owner = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
terminal.Owner.Faction = faction
terminal.GUID = PlanetSideGUID(1)
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), terminal)

View file

@ -13,7 +13,7 @@ class OrderTerminalTest extends Specification {
val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)
val player = Player(avatar)
val building = new Building(0, Zone.Nowhere, StructureType.Building)
val building = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
building.Faction = PlanetSideEmpire.TR
val infantryTerminal = Terminal(GlobalDefinitions.order_terminal)
infantryTerminal.Owner = building

View file

@ -109,7 +109,7 @@ class ProximityTerminalControlStartTest extends ActorTest {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
@ -153,7 +153,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
@ -205,7 +205,7 @@ class ProximityTerminalControlStopTest extends ActorTest {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}
@ -256,7 +256,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest {
AddPool("dynamic", 1 to 10)
}
}
new Building(0, zone, StructureType.Facility) {
new Building(building_guid = 0, map_id = 0, zone, StructureType.Facility) {
Amenities = terminal
Faction = PlanetSideEmpire.VS
}

View file

@ -121,7 +121,7 @@ object TerminalControlTest {
def SetUpAgents(tdef : TerminalDefinition, faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, Terminal) = {
val terminal = Terminal(tdef)
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-term")
terminal.Owner = new Building(0, Zone.Nowhere, StructureType.Building)
terminal.Owner = new Building(building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building)
terminal.Owner.Faction = faction
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), terminal)
}

File diff suppressed because it is too large Load diff

View file

@ -482,8 +482,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
var ori = spawn_tube.Orientation
spawn_tube.Owner match {
case building : Building =>
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in building ${building.Id} selected")
pos = pos + (Vector3(0, 0, 1.5f))
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in building ${building.MapId} selected")
val respawn_z_offset = 1.5f // Offset the spawn tube slightly, so the player doesn't spawn in the floor. This value comes from startup.pak/game_objects.adb.lst -> mb_respawn_tube respawn_z_offset setting
pos += Vector3(0, 0, respawn_z_offset)
ori += Vector3(0, 0, 90f) // Since all spawn tubes seem to have a zero orientation, we need to offset by 90 degrees so the player faces north towards the door, not east.
case vehicle : Vehicle =>
// vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(vehicle), continent))
// vehicleService ! VehicleServiceMessage.Decon(RemoverActor.AddTask(vehicle, continent, vehicle.Definition.DeconstructionTime))
@ -769,7 +771,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(FriendsResponse(FriendAction.InitializeIgnoreList, 0, true, true, Nil))
avatarService ! Service.Join(avatar.name) //channel will be player.Name
localService ! Service.Join(avatar.name) //channel will be player.Name
cluster ! InterstellarCluster.GetWorld("z6")
cluster ! InterstellarCluster.GetWorld("z4")
case InterstellarCluster.GiveWorld(zoneId, zone) =>
log.info(s"Zone $zoneId will now load")
@ -1911,7 +1913,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
case VehicleResponse.DetachFromRails(vehicle_guid, pad_guid, pad_position, pad_orientation_z) =>
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0, 0, 0.5f), pad_orientation_z))
//todo: dropship_pad_doors should have a different offset
val vehicle_creation_z_offset = 2.52604f // This value comes from startup.pak/game_objects.adb.lst -> mb_pad_creation vehiclecreationzoffset
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0, 0, vehicle_creation_z_offset), pad_orientation_z))
case VehicleResponse.EquipmentInSlot(pkt) =>
if(tplayer_guid != guid) {
@ -3539,7 +3543,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
// TODO: Not all incoming UseItemMessage's respond with another UseItemMessage (i.e. doors only send out GenericObjectStateMsg)
continent.GUID(object_guid) match {
case Some(door : Door) =>
if(player.Faction == door.Faction || ((continent.Map.DoorToLock.get(object_guid.guid) match {
if(player.Faction == door.Faction || (continent.Map.DoorToLock.get(object_guid.guid) match {
case Some(lock_guid) =>
val lock = continent.GUID(lock_guid).get.asInstanceOf[IFFLock]
@ -3550,11 +3554,16 @@ class WorldSessionActor extends Actor with MDCContextAware {
case None => ;
}
// If the IFF lock has been hacked OR the base is neutral OR the base linked to the lock is hacked then open the door
lock.HackedBy.isDefined || baseIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL
case None => !door.isOpen
}) || Vector3.ScalarProjection(door.Outwards, player.Position - door.Position) < 0f)) {
// We're on the inside of the door - open the door
val playerIsOnInside = Vector3.ScalarProjection(lock.Outwards, player.Position - door.Position) < 0f
// If an IFF lock exists and the IFF lock faction doesn't match the current player and one of the following conditions are met open the door:
// A base is neutral
// A base is hacked
// The lock is hacked
// The player is on the inside of the door, determined by the lock orientation
lock.HackedBy.isDefined || baseIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL || playerIsOnInside
case None => !door.isOpen // If there's no linked IFF lock just open the door if it's closed.
})) {
door.Actor ! Door.Use(player, msg)
}
else if(door.isOpen) {
@ -5974,7 +5983,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
*/
def configZone(zone : Zone) : Unit = {
zone.Buildings.values.foreach(building => {
sendResponse(SetEmpireMessage(PlanetSideGUID(building.ModelId), building.Faction))
sendResponse(SetEmpireMessage(building.GUID, building.Faction))
building.Amenities.foreach(amenity => {
val amenityId = amenity.GUID
sendResponse(PlanetsideAttributeMessage(amenityId, 50, 0))

View file

@ -16,38 +16,67 @@ object Zones {
override def Init(implicit context : ActorContext) : Unit = {
super.Init(context)
import net.psforever.types.PlanetSideEmpire
Building(5).get.Faction = PlanetSideEmpire.NEUTRAL //Akkan
Building(5).get.ModelId = 24
// Building(6).get.Faction = PlanetSideEmpire.TR //Baal
// Building(6).get.ModelId = 42
// Building(7).get.Faction = PlanetSideEmpire.TR //Dagon
// Building(7).get.ModelId = 27
Building(9).get.Faction = PlanetSideEmpire.NC //Girru
Building(9).get.ModelId = 48
Building(10).get.Faction = PlanetSideEmpire.TR //Hanish
Building(10).get.ModelId = 30
Building(11).get.Faction = PlanetSideEmpire.VS //Irkalla
Building(11).get.ModelId = 21
//// Building(13).get.Faction = PlanetSideEmpire.VS //Lahar
Building(25).get.Faction = PlanetSideEmpire.VS //Gate Outpost Watch Tower (North of Forseral Warpgate)
Building(25).get.ModelId = 74
Building(33).get.Faction = PlanetSideEmpire.TR //East Girru Gun Tower
Building(33).get.ModelId = 62
Building(34).get.Faction = PlanetSideEmpire.TR //SE Hanish Gun Tower
Building(34).get.ModelId = 60
Building(35).get.Faction = PlanetSideEmpire.TR //Northeast Akkan Watch tower
Building(35).get.ModelId = 69
Building(36).get.Faction = PlanetSideEmpire.VS //West Girru Air Tower
Building(36).get.ModelId = 83
Building(55).get.Faction = PlanetSideEmpire.NC //South Irkalla Air Tower
Building(55).get.ModelId = 86
Building(56).get.Faction = PlanetSideEmpire.NC //Southwest Hanish Air Tower
Building(56).get.ModelId = 82
Building(59).get.Faction = PlanetSideEmpire.NC //Gate Outpost Watch Tower (South of Cyssor Warpgate)
Building(59).get.ModelId = 73
Building(65).get.Faction = PlanetSideEmpire.TR //West Hanish Gun Tower
Building(65).get.ModelId = 56
BuildingByMapId(5).Faction = PlanetSideEmpire.TR //Akkan
BuildingByMapId(6).Faction = PlanetSideEmpire.TR //Baal
BuildingByMapId(7).Faction = PlanetSideEmpire.TR //Dagon
BuildingByMapId(8).Faction = PlanetSideEmpire.NC //Enkidu
BuildingByMapId(9).Faction = PlanetSideEmpire.VS //Girru
BuildingByMapId(10).Faction = PlanetSideEmpire.VS //Hanish
BuildingByMapId(11).Faction = PlanetSideEmpire.VS //Irkalla
BuildingByMapId(12).Faction = PlanetSideEmpire.VS //Kusag
BuildingByMapId(13).Faction = PlanetSideEmpire.VS //Lahar
BuildingByMapId(14).Faction = PlanetSideEmpire.NC //Marduk
BuildingByMapId(15).Faction = PlanetSideEmpire.NC //Neti
BuildingByMapId(16).Faction = PlanetSideEmpire.NC //Zaqar
BuildingByMapId(17).Faction = PlanetSideEmpire.NC //S_Marduk_Tower
BuildingByMapId(18).Faction = PlanetSideEmpire.NC //W_Neti_Tower
BuildingByMapId(19).Faction = PlanetSideEmpire.NC //W_Zaqar_Tower
BuildingByMapId(20).Faction = PlanetSideEmpire.NC //E_Zaqar_Tower
BuildingByMapId(21).Faction = PlanetSideEmpire.NC //NE_Neti_Tower
BuildingByMapId(22).Faction = PlanetSideEmpire.NC //SE_Ceryshen_Warpgate_Tower
BuildingByMapId(23).Faction = PlanetSideEmpire.VS //S_Kusag_Tower
BuildingByMapId(24).Faction = PlanetSideEmpire.VS //NW_Kusag_Tower
BuildingByMapId(25).Faction = PlanetSideEmpire.VS //N_Ceryshen_Warpgate_Tower
BuildingByMapId(26).Faction = PlanetSideEmpire.VS //SE_Irkalla_Tower
BuildingByMapId(27).Faction = PlanetSideEmpire.VS //S_Irkalla_Tower
BuildingByMapId(28).Faction = PlanetSideEmpire.TR //NE_Enkidu_Tower
BuildingByMapId(29).Faction = PlanetSideEmpire.NC //SE_Akkan_Tower
BuildingByMapId(30).Faction = PlanetSideEmpire.NC //SW_Enkidu_Tower
BuildingByMapId(31).Faction = PlanetSideEmpire.TR //E_Searhus_Warpgate_Tower
BuildingByMapId(32).Faction = PlanetSideEmpire.TR //N_Searhus_Warpgate_Tower
BuildingByMapId(33).Faction = PlanetSideEmpire.VS //E_Girru_Tower
BuildingByMapId(34).Faction = PlanetSideEmpire.VS //SE_Hanish_Tower
BuildingByMapId(35).Faction = PlanetSideEmpire.TR //SW_Hanish_Tower
BuildingByMapId(36).Faction = PlanetSideEmpire.VS //W_Girru_Tower
BuildingByMapId(37).Faction = PlanetSideEmpire.TR //E_Dagon_Tower
BuildingByMapId(38).Faction = PlanetSideEmpire.TR //NE_Baal_Tower
BuildingByMapId(39).Faction = PlanetSideEmpire.TR //SE_Baal_Tower
BuildingByMapId(40).Faction = PlanetSideEmpire.TR //S_Dagon_Tower
BuildingByMapId(41).Faction = PlanetSideEmpire.NC //W_Ceryshen_Warpgate_Tower
BuildingByMapId(42).Faction = PlanetSideEmpire.NEUTRAL //dagon bunker
BuildingByMapId(43).Faction = PlanetSideEmpire.NEUTRAL //Akkan North Bunker
BuildingByMapId(44).Faction = PlanetSideEmpire.NEUTRAL //Enkidu East Bunker
BuildingByMapId(45).Faction = PlanetSideEmpire.NEUTRAL //Neti bunker
BuildingByMapId(46).Faction = PlanetSideEmpire.NEUTRAL //Hanish West Bunker
BuildingByMapId(47).Faction = PlanetSideEmpire.NEUTRAL //Irkalla East Bunker
BuildingByMapId(48).Faction = PlanetSideEmpire.NEUTRAL //Zaqar bunker
BuildingByMapId(49).Faction = PlanetSideEmpire.NEUTRAL //Kusag West Bunker
BuildingByMapId(50).Faction = PlanetSideEmpire.NEUTRAL //marduk bunker
BuildingByMapId(51).Faction = PlanetSideEmpire.TR //baal bunker
BuildingByMapId(52).Faction = PlanetSideEmpire.NEUTRAL //girru bunker
BuildingByMapId(53).Faction = PlanetSideEmpire.NEUTRAL //lahar bunker
BuildingByMapId(54).Faction = PlanetSideEmpire.NEUTRAL //akkan bunker
BuildingByMapId(55).Faction = PlanetSideEmpire.VS //Irkalla_Tower
BuildingByMapId(56).Faction = PlanetSideEmpire.VS //Hanish_Tower
BuildingByMapId(57).Faction = PlanetSideEmpire.VS //E_Ceryshen_Warpgate_Tower
BuildingByMapId(58).Faction = PlanetSideEmpire.VS //Lahar_Tower
BuildingByMapId(59).Faction = PlanetSideEmpire.VS //VSSanc_Warpgate_Tower
BuildingByMapId(60).Faction = PlanetSideEmpire.TR //Akkan_Tower
BuildingByMapId(61).Faction = PlanetSideEmpire.NC //TRSanc_Warpgate_Tower
BuildingByMapId(62).Faction = PlanetSideEmpire.NC //Marduk_Tower
BuildingByMapId(63).Faction = PlanetSideEmpire.TR //NW_Dagon_Tower
BuildingByMapId(64).Faction = PlanetSideEmpire.NEUTRAL //E7 East Bunker (at north from bridge)
BuildingByMapId(65).Faction = PlanetSideEmpire.VS //W_Hanish_Tower
}
}
@ -58,14 +87,14 @@ object Zones {
super.Init(context)
import net.psforever.types.PlanetSideEmpire
Building(2).get.Faction = PlanetSideEmpire.VS
Building(2).get.ModelId = 20
Building(38).get.ModelId = 0
Building(42).get.ModelId = 0
Building(48).get.Faction = PlanetSideEmpire.VS
Building(48).get.ModelId = 59
Building(49).get.Faction = PlanetSideEmpire.VS
Building(49).get.ModelId = 69
// Building(2).get.Faction = PlanetSideEmpire.VS
// Building(2).get.ModelId = 20
// Building(38).get.ModelId = 0
// Building(42).get.ModelId = 0
// Building(48).get.Faction = PlanetSideEmpire.VS
// Building(48).get.ModelId = 59
// Building(49).get.Faction = PlanetSideEmpire.VS
// Building(49).get.ModelId = 69
}
}
@ -101,11 +130,11 @@ object Zones {
import net.psforever.types.PlanetSideEmpire
Buildings.values.foreach { _.Faction = PlanetSideEmpire.VS }
Building(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower
GUID(293).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 52
GUID(706).get.asInstanceOf[VehicleSpawnPad].Guide = List(AutoDriveControls.DistanceFromHere(50f)) //building 77
GUID(710).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 79
GUID(712).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 81
// Building(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower
// GUID(293).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 52
// GUID(706).get.asInstanceOf[VehicleSpawnPad].Guide = List(AutoDriveControls.DistanceFromHere(50f)) //building 77
// GUID(710).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 79
// GUID(712).get.asInstanceOf[VehicleSpawnPad].Railed = false //building 81
}
}