mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
added sidedness to different entities, both in general and depending on the zone where it matters
This commit is contained in:
parent
4508c1ae45
commit
84b3d2297a
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.doors
|
|||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.UseItemMessage
|
||||
import net.psforever.types.Vector3
|
||||
|
|
@ -14,6 +15,13 @@ import net.psforever.types.Vector3
|
|||
class Door(private val ddef: DoorDefinition) extends Amenity {
|
||||
private var openState: Option[Player] = None
|
||||
private var outwards: Option[Vector3] = None
|
||||
/*
|
||||
* Door sidedness does not reflect on the actual sidedness of anything that is in the door.
|
||||
* While sidedness will be correct for internal doors -
|
||||
* they are always passages between different between interior rooms in a facility -
|
||||
* external doors cross between the outside world and a interior room of a facility.
|
||||
*/
|
||||
WhichSide = Sidedness.InsideOf
|
||||
|
||||
def isOpen: Boolean = openState.isDefined
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import akka.actor.ActorRef
|
|||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.TriggeredSound
|
||||
import net.psforever.types.Vector3
|
||||
|
|
@ -23,6 +24,7 @@ class IFFLock(private val idef: IFFLockDefinition) extends Amenity with Hackable
|
|||
HackSound = TriggeredSound.HackDoor
|
||||
HackEffectDuration = Array(60, 180, 300, 360)
|
||||
HackDuration = Array(5, 3, 1, 1)
|
||||
WhichSide = Sidedness.InsideOf
|
||||
|
||||
/** a vector in the direction of the "outside" of a room;
|
||||
* typically, any locking utility is on that same "outside"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.{Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
|
|
@ -18,6 +19,8 @@ import net.psforever.types.PlanetSideGUID
|
|||
* @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class VehicleSpawnPad(spDef: VehicleSpawnPadDefinition) extends Amenity {
|
||||
WhichSide = Sidedness.OutsideOf
|
||||
|
||||
def Definition: VehicleSpawnPadDefinition = spDef
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad.process
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
|
|
@ -29,11 +29,11 @@ import scala.util.Success
|
|||
class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnControlBase(pad) {
|
||||
def LogId = "-loader"
|
||||
|
||||
val railJack = context.actorOf(Props(classOf[VehicleSpawnControlRailJack], pad), s"${context.parent.path.name}-rails")
|
||||
val railJack: ActorRef = context.actorOf(Props(classOf[VehicleSpawnControlRailJack], pad), s"${context.parent.path.name}-rails")
|
||||
|
||||
var temp: Option[VehicleSpawnControl.Order] = None
|
||||
|
||||
implicit val timeout = Timeout(3.seconds)
|
||||
implicit val timeout: Timeout = Timeout(3.seconds)
|
||||
|
||||
def receive: Receive = {
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
|
|
@ -42,6 +42,7 @@ class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnC
|
|||
vehicle.Position = vehicle.Position - Vector3.z(
|
||||
if (GlobalDefinitions.isFlightVehicle(vehicle.Definition)) 9 else 5
|
||||
) //appear below the trench and doors
|
||||
vehicle.WhichSide = pad.WhichSide
|
||||
vehicle.Cloaked = vehicle.Definition.CanCloak && driver.Cloaked
|
||||
|
||||
temp = Some(order)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
package net.psforever.objects.serverobject.resourcesilo
|
||||
|
||||
import akka.actor.{ActorContext, Props}
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.{CommonNtuContainer, GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.UseItemMessage
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
class ResourceSilo extends Amenity with CommonNtuContainer {
|
||||
|
||||
// For the flashing red light on top of the NTU silo on.
|
||||
|
|
@ -16,6 +19,7 @@ class ResourceSilo extends Amenity with CommonNtuContainer {
|
|||
// For the NTU display bar
|
||||
private var capacitorDisplay: Long = 0
|
||||
NtuCapacitor = Definition.MaxNtuCapacitor
|
||||
WhichSide = Sidedness.OutsideOf
|
||||
|
||||
def MaxNtuCapacitor : Float = Definition.MaxNtuCapacitor
|
||||
|
||||
|
|
@ -37,7 +41,7 @@ class ResourceSilo extends Amenity with CommonNtuContainer {
|
|||
|
||||
def Definition: ResourceSiloDefinition = GlobalDefinitions.resource_silo
|
||||
|
||||
def Use(player: Player, msg: UseItemMessage): ResourceSilo.Exchange = {
|
||||
def Use(@unused player: Player, @unused msg: UseItemMessage): ResourceSilo.Exchange = {
|
||||
ResourceSilo.ChargeEvent()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.interior.{Sidedness, TraditionalInteriorAware}
|
||||
import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.vital.resolution.DamageAndResistance
|
||||
|
|
@ -25,7 +26,8 @@ abstract class Amenity
|
|||
extends PlanetSideServerObject
|
||||
with Vitality
|
||||
with StandardResistanceProfile
|
||||
with BlockMapEntity {
|
||||
with BlockMapEntity
|
||||
with TraditionalInteriorAware {
|
||||
private[this] val log = org.log4s.getLogger("Amenity")
|
||||
|
||||
/** what other entity has authority over this amenity; usually either a building or a vehicle */
|
||||
|
|
@ -34,6 +36,8 @@ abstract class Amenity
|
|||
/** if the entity exists at a specific position relative to the owner's position */
|
||||
private var offset: Option[Vector3] = None
|
||||
|
||||
WhichSide = Sidedness.InsideOf
|
||||
|
||||
def Faction: PlanetSideEmpire.Value = Owner.Faction
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.{Default, Player}
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
|
|
@ -17,6 +18,8 @@ import net.psforever.services.Service
|
|||
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class ProximityTerminal(tdef: ProximityTerminalDefinition) extends Terminal(tdef) with ProximityUnit {
|
||||
WhichSide = Sidedness.StrictlyBetweenSides
|
||||
|
||||
override def Request(player: Player, msg: Any): Terminal.Exchange = {
|
||||
msg match {
|
||||
case message: CommonMessages.Use =>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.serverobject.turret
|
||||
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, AmenityOwner, Building}
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalAware
|
||||
import net.psforever.objects.serverobject.turret.auto.AutomatedTurret
|
||||
|
|
@ -14,6 +15,7 @@ class FacilityTurret(tDef: FacilityTurretDefinition)
|
|||
with JammableUnit
|
||||
with CaptureTerminalAware {
|
||||
WeaponTurret.LoadDefinition(turret = this)
|
||||
WhichSide = Sidedness.OutsideOf
|
||||
|
||||
def TurretOwner: SourceEntry = {
|
||||
Seats
|
||||
|
|
@ -36,7 +38,6 @@ class FacilityTurret(tDef: FacilityTurretDefinition)
|
|||
}
|
||||
|
||||
object FacilityTurret {
|
||||
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @param tDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
|
|
|
|||
|
|
@ -319,7 +319,6 @@ class VehicleControl(vehicle: Vehicle)
|
|||
case Some(seatNumber) =>
|
||||
val vsrc = VehicleSource(vehicle)
|
||||
user.LogActivity(VehicleMountActivity(vsrc, PlayerSource.inSeat(user, vsrc, seatNumber), vehicle.Zone.Number))
|
||||
obj.WhichSide = user.WhichSide
|
||||
//if the driver mount, change ownership if that is permissible for this vehicle
|
||||
if (seatNumber == 0 && !obj.OwnerName.contains(user.Name) && obj.Definition.CanBeOwned.nonEmpty) {
|
||||
//whatever vehicle was previously owned
|
||||
|
|
|
|||
|
|
@ -42,8 +42,10 @@ import net.psforever.objects.serverobject.affinity.FactionAffinity
|
|||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.interior.{InteriorAware, Sidedness}
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech
|
||||
import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad
|
||||
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.sourcing.SourceEntry
|
||||
import net.psforever.objects.vehicles.{MountedWeapons, UtilityType}
|
||||
|
|
@ -662,11 +664,11 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
|||
(buildings.get(building_id), guid(object_guid)) match {
|
||||
case (Some(building), Some(amenity: Amenity)) =>
|
||||
building.Amenities = amenity
|
||||
//amenity.History(EntitySpawn(SourceEntry(amenity), this))
|
||||
case (Some(_), _) | (None, _) | (_, None) => ; //let ZoneActor's sanity check catch this error
|
||||
case (Some(_), _) | (None, _) | (_, None) => () //let ZoneActor's sanity check catch this error
|
||||
}
|
||||
})
|
||||
Zone.AssignDoors(zone = this)
|
||||
Zone.AssignOutwardSideToDoors(zone = this)
|
||||
Zone.AssignSidednessToAmenities(zone = this)
|
||||
//ntu management (eventually move to a generic building startup function)
|
||||
buildings.values
|
||||
.flatMap(_.Amenities.filter(_.Definition == GlobalDefinitions.resource_silo))
|
||||
|
|
@ -880,11 +882,10 @@ object Zone {
|
|||
new Zone(id, map, number)
|
||||
}
|
||||
|
||||
private def AssignDoors(zone: Zone): Unit = {
|
||||
private def AssignOutwardSideToDoors(zone: Zone): Unit = {
|
||||
//let ZoneActor's sanity check catch any missing entities
|
||||
val map = zone.map
|
||||
if (map.cavern) {
|
||||
//cavern doors
|
||||
//todo there are no doors in the training zones so we may skip that
|
||||
if (zone.map.cavern) {
|
||||
//todo what do?
|
||||
//almost all are type ancient_door and don't have many hints to determine outward-ness; there are no IFF locks
|
||||
} else if (
|
||||
|
|
@ -892,107 +893,269 @@ object Zone {
|
|||
.filterNot(_ == PlanetSideEmpire.NEUTRAL)
|
||||
.exists(fac => Zones.sanctuaryZoneNumber(fac) == zone.Number)
|
||||
) {
|
||||
//sanctuary doors
|
||||
AssignIFFLockedDoors(zone)
|
||||
//spawn building doors
|
||||
val buildings = zone.Buildings.values
|
||||
val amenityList = buildings
|
||||
.collect {
|
||||
case b
|
||||
if b.Definition.Name.startsWith("VT_building_") =>
|
||||
val amenities = b.Amenities
|
||||
(
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_ext),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_lrg),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.order_terminal),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.respawn_tube_sanctuary)
|
||||
)
|
||||
}
|
||||
amenityList.foreach { case (entranceDoors, _, terminals, tubes) =>
|
||||
entranceDoors.foreach { door =>
|
||||
val doorPosition = door.Position
|
||||
val closestTerminal = terminals.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
val closestTube = tubes.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
door.asInstanceOf[Door].Outwards = Vector3.Unit(closestTerminal.Position.xy - closestTube.Position.xy)
|
||||
}
|
||||
//todo training zone warp chamber doors
|
||||
}
|
||||
//hart building doors
|
||||
buildings
|
||||
.collect {
|
||||
case b
|
||||
if b.Definition.Name.startsWith("orbital_building_") =>
|
||||
val amenities = b.Amenities
|
||||
(
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_ext),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_orb)
|
||||
)
|
||||
}
|
||||
.foreach { case (entranceDoors, hartDoors) =>
|
||||
entranceDoors.foreach { door =>
|
||||
val doorPosition = door.Position
|
||||
val closestHartDoor = hartDoors.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
door.asInstanceOf[Door].Outwards = Vector3.Unit(doorPosition.xy - closestHartDoor.Position.xy)
|
||||
}
|
||||
}
|
||||
AssignOutwardSideToSanctuaryDoors(zone)
|
||||
} else {
|
||||
//above ground zone doors
|
||||
AssignIFFLockedDoors(zone)
|
||||
//for major facilities, external doors in the courtyard are without locks but are paired in opposing directions
|
||||
val unpairedDoors = zone.Buildings
|
||||
.values
|
||||
.collect {
|
||||
case b
|
||||
if b.BuildingType == StructureType.Facility && b.Amenities.nonEmpty =>
|
||||
b.Amenities.collect {
|
||||
case d: Door
|
||||
if d.Definition == GlobalDefinitions.gr_door_ext && d.Outwards == Vector3.Zero =>
|
||||
d
|
||||
}
|
||||
AssignOutwardSidetoContinentDoors(zone)
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignOutwardSideToSanctuaryDoors(zone: Zone): Unit = {
|
||||
val map = zone.map
|
||||
val guid = zone.guid
|
||||
AssignOutwardsToIFFLockedDoors(zone)
|
||||
//doors with IFF locks belong to towers and are always between; the locks are always outside
|
||||
map.doorToLock
|
||||
.map { case (door, lock) => (guid(door), guid(lock)) }
|
||||
.collect { case (Some(door: Door), Some(lock: IFFLock)) =>
|
||||
door.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//spawn building doors
|
||||
val buildings = zone.Buildings.values
|
||||
val amenityList = buildings
|
||||
.collect {
|
||||
case b
|
||||
if b.Definition.Name.startsWith("VT_building_") =>
|
||||
val amenities = b.Amenities
|
||||
(
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_ext),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_lrg),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.order_terminal),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.respawn_tube_sanctuary)
|
||||
)
|
||||
}
|
||||
amenityList.foreach { case (entranceDoors, _, terminals, tubes) =>
|
||||
entranceDoors.foreach { door =>
|
||||
val isReallyADoor = door.asInstanceOf[Door]
|
||||
val doorPosition = door.Position
|
||||
val closestTerminal = terminals.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
val closestTube = tubes.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
isReallyADoor.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
isReallyADoor.Outwards = Vector3.Unit(closestTerminal.Position.xy - closestTube.Position.xy)
|
||||
}
|
||||
//todo training zone warp chamber doors
|
||||
}
|
||||
//hart building doors
|
||||
buildings
|
||||
.collect {
|
||||
case b
|
||||
if b.Definition.Name.startsWith("orbital_building_") =>
|
||||
val amenities = b.Amenities
|
||||
(
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_ext),
|
||||
amenities.filter(_.Definition == GlobalDefinitions.gr_door_mb_orb)
|
||||
)
|
||||
}
|
||||
.foreach { case (entranceDoors, hartDoors) =>
|
||||
entranceDoors.foreach { door =>
|
||||
val isReallyADoor = door.asInstanceOf[Door]
|
||||
val doorPosition = door.Position
|
||||
val closestHartDoor = hartDoors.minBy(t => Vector3.DistanceSquared(doorPosition, t.Position))
|
||||
isReallyADoor.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
isReallyADoor.Outwards = Vector3.Unit(doorPosition.xy - closestHartDoor.Position.xy)
|
||||
}
|
||||
var pairedDoors = Seq[(Door, Door)]()
|
||||
unpairedDoors.foreach { buildingUnPairedDoors =>
|
||||
var volatileUnpairedDoors = buildingUnPairedDoors
|
||||
while (volatileUnpairedDoors.size > 1) {
|
||||
val sampleDoor = volatileUnpairedDoors.head
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignOutwardSidetoContinentDoors(zone: Zone): Unit = {
|
||||
val map = zone.map
|
||||
val guid = zone.guid
|
||||
AssignOutwardsToIFFLockedDoors(zone)
|
||||
val buildingsToDoors = zone.Buildings.values.map(b => (b, b.Amenities.collect { case d: Door => d })).toMap
|
||||
//external doors with IFF locks are always between and outside, respectively
|
||||
map.doorToLock
|
||||
.map { case (door, lock) => (guid(door), guid(lock)) }
|
||||
.collect { case (Some(door: Door), Some(lock: IFFLock))
|
||||
if door.Definition.geometryInteractionRadius.nonEmpty =>
|
||||
door.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//for major facilities, external doors in the courtyard are paired, connected by a passage between ground and walls
|
||||
//they are the only external doors that do not have iff locks
|
||||
buildingsToDoors
|
||||
.filter { case (b, _) => b.BuildingType == StructureType.Facility }
|
||||
.foreach { case (_, doors) =>
|
||||
var unpairedDoors = doors.collect {
|
||||
case d: Door
|
||||
if d.Definition == GlobalDefinitions.gr_door_ext && !map.doorToLock.contains(d.GUID.guid) =>
|
||||
d
|
||||
}
|
||||
var pairedDoors = Seq[(Door, Door)]()
|
||||
while (unpairedDoors.size > 1) {
|
||||
val sampleDoor = unpairedDoors.head
|
||||
val sampleDoorPosition = sampleDoor.Position.xy
|
||||
val distances = Float.MaxValue +: volatileUnpairedDoors
|
||||
val distances = Float.MaxValue +: unpairedDoors
|
||||
.map(d => Vector3.DistanceSquared(d.Position.xy, sampleDoorPosition))
|
||||
.drop(1)
|
||||
val min = distances.min
|
||||
val indexOfClosestDoor = distances.indexWhere(_ == min)
|
||||
val otherDoor = volatileUnpairedDoors(indexOfClosestDoor)
|
||||
volatileUnpairedDoors = volatileUnpairedDoors.slice(1, indexOfClosestDoor) ++ volatileUnpairedDoors.drop(indexOfClosestDoor + 1)
|
||||
val otherDoor = unpairedDoors(indexOfClosestDoor)
|
||||
unpairedDoors = unpairedDoors.slice(1, indexOfClosestDoor) ++ unpairedDoors.drop(indexOfClosestDoor + 1)
|
||||
pairedDoors = pairedDoors :+ (sampleDoor, otherDoor)
|
||||
}
|
||||
pairedDoors.foreach { case (door1, door2) =>
|
||||
//give each paired courtyard door an outward-ness
|
||||
val outwards = Vector3.Unit(door1.Position.xy - door2.Position.xy)
|
||||
door1.Outwards = outwards
|
||||
door1.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
door2.Outwards = Vector3.neg(outwards)
|
||||
door2.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
}
|
||||
}
|
||||
pairedDoors.foreach { case (door1, door2) =>
|
||||
//give each paired courtyard door an outward-ness
|
||||
val outwards = Vector3.Unit(door1.Position.xy - door2.Position.xy)
|
||||
door1.Outwards = outwards
|
||||
door2.Outwards = Vector3.neg(outwards)
|
||||
//bunkers do not define a formal interior, so their doors are solely exterior
|
||||
buildingsToDoors
|
||||
.filter { case (b, _) => b.BuildingType == StructureType.Bunker }
|
||||
.foreach { case (_, doors) =>
|
||||
doors.foreach(_.WhichSide = Sidedness.OutsideOf)
|
||||
}
|
||||
//bunker doors do not define an interior
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignIFFLockedDoors(zone: Zone): Unit = {
|
||||
val map = zone.map
|
||||
private def AssignOutwardsToIFFLockedDoors(zone: Zone): Unit = {
|
||||
val guid = zone.guid
|
||||
val invalidOutwards = Vector3(0,0,-1) //down
|
||||
//doors with nearby locks use those locks as their unlocking mechanism and their outwards indication
|
||||
map.doorToLock
|
||||
zone.map.doorToLock
|
||||
.map { case (doorGUID: Int, lockGUID: Int) => (guid(doorGUID), guid(lockGUID)) }
|
||||
.collect {
|
||||
case (Some(door: Door), Some(lock: IFFLock)) =>
|
||||
door.Outwards = lock.Outwards
|
||||
door.Actor ! Door.UpdateMechanism(IFFLock.testLock(lock))
|
||||
case (Some(door: Door), _) =>
|
||||
door.Outwards = invalidOutwards
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignSidednessToAmenities(zone: Zone): Unit = {
|
||||
//let ZoneActor's sanity check catch any missing entities
|
||||
//todo training zones, where everything is outside
|
||||
if (zone.map.cavern) {
|
||||
//todo what do?
|
||||
/*
|
||||
quite a few amenities are disconnected from buildings
|
||||
there are two orientations of terminal/spawn pad
|
||||
as aforementioned, door outwards and sidedness is not assignable at the moment
|
||||
*/
|
||||
} else if (
|
||||
PlanetSideEmpire.values
|
||||
.filterNot(_ == PlanetSideEmpire.NEUTRAL)
|
||||
.exists(fac => Zones.sanctuaryZoneNumber(fac) == zone.Number)
|
||||
) {
|
||||
AssignSidednessToSanctuaryAmenities(zone)
|
||||
} else {
|
||||
AssignSidednessToContinentAmenities(zone)
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignSidednessToSanctuaryAmenities(zone: Zone): Unit = {
|
||||
val map = zone.map
|
||||
val guid = zone.guid
|
||||
//only tower doors possess locks and those are always external
|
||||
map.doorToLock
|
||||
.map { case (_, lock) => guid(lock) }
|
||||
.collect {
|
||||
case Some(lock: IFFLock) =>
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//medical terminals are always inside
|
||||
zone.buildings
|
||||
.values
|
||||
.flatMap(_.Amenities)
|
||||
.collect {
|
||||
case pt: ProximityTerminal if pt.Definition == GlobalDefinitions.medical_terminal =>
|
||||
pt.WhichSide = Sidedness.InsideOf
|
||||
}
|
||||
//repair silos and landing pads have multiple components and all of these are outside
|
||||
//we have to search all terminal entities because the repair silos are not installed anywhere
|
||||
guid
|
||||
.GetPool(name = "terminals")
|
||||
.map(_.Numbers.flatMap(number => guid(number)))
|
||||
.getOrElse(List())
|
||||
.collect {
|
||||
case pt: ProximityTerminal
|
||||
if pt.Definition == GlobalDefinitions.repair_silo =>
|
||||
val guid = pt.GUID.guid
|
||||
Seq(guid, guid + 1, guid + 2, guid + 3)
|
||||
case pt: ProximityTerminal
|
||||
if pt.Definition.Name.startsWith("pad_landing_") =>
|
||||
val guid = pt.GUID.guid
|
||||
Seq(guid, guid + 1, guid + 2)
|
||||
}
|
||||
.flatten[Int]
|
||||
.map(guid(_))
|
||||
.collect {
|
||||
case Some(pt: ProximityTerminal) =>
|
||||
pt.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//the following terminals are installed outside
|
||||
map.terminalToSpawnPad
|
||||
.keys
|
||||
.flatMap(guid(_))
|
||||
.collect {
|
||||
case terminal: Terminal =>
|
||||
terminal.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
}
|
||||
|
||||
private def AssignSidednessToContinentAmenities(zone: Zone): Unit = {
|
||||
val map = zone.map
|
||||
val guid = zone.guid
|
||||
val buildingsMap = zone.buildings.values
|
||||
//door locks on external doors are also external while the door is merely "between"; all other locks are internal
|
||||
map.doorToLock
|
||||
.map { case (door, lock) => (guid(door), guid(lock))}
|
||||
.collect {
|
||||
case (Some(door: Door), Some(lock: IFFLock))
|
||||
if door.Definition.geometryInteractionRadius.nonEmpty =>
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//medical terminals are always inside
|
||||
buildingsMap
|
||||
.flatMap(_.Amenities)
|
||||
.collect {
|
||||
case pt: ProximityTerminal
|
||||
if pt.Definition == GlobalDefinitions.medical_terminal || pt.Definition == GlobalDefinitions.adv_med_terminal =>
|
||||
pt.WhichSide = Sidedness.InsideOf
|
||||
}
|
||||
//repair silos and landing pads have multiple components and all of these are outside
|
||||
buildingsMap
|
||||
.flatMap(_.Amenities)
|
||||
.collect {
|
||||
case pt: ProximityTerminal
|
||||
if pt.Definition == GlobalDefinitions.repair_silo =>
|
||||
val guid = pt.GUID.guid
|
||||
Seq(guid, guid + 1, guid + 2, guid + 3)
|
||||
case pt: ProximityTerminal
|
||||
if pt.Definition.Name.startsWith("pad_landing_") =>
|
||||
val guid = pt.GUID.guid
|
||||
Seq(guid, guid + 1, guid + 2)
|
||||
}
|
||||
.toSeq
|
||||
.flatten[Int]
|
||||
.map(guid(_))
|
||||
.collect {
|
||||
case Some(pt: ProximityTerminal) =>
|
||||
pt.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//all vehicle spawn pads are outside, save for the ground vehicle pad in the tech plants
|
||||
buildingsMap.collect {
|
||||
case b
|
||||
if b.Definition == GlobalDefinitions.tech_plant =>
|
||||
b.Amenities
|
||||
.collect { case pad: VehicleSpawnPad => pad }
|
||||
.minBy(_.Position.z)
|
||||
.WhichSide = Sidedness.InsideOf
|
||||
}
|
||||
//all vehicle terminals are outside of their owning facilities in the courtyard
|
||||
//the only exceptions are vehicle terminals in tech plants and the dropship center air terminal
|
||||
map.terminalToSpawnPad
|
||||
.keys
|
||||
.flatMap(guid(_))
|
||||
.collect {
|
||||
case terminal: Terminal
|
||||
if terminal.Definition != GlobalDefinitions.dropship_vehicle_terminal &&
|
||||
terminal.Owner.asInstanceOf[Building].Definition != GlobalDefinitions.tech_plant =>
|
||||
terminal.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
}
|
||||
|
||||
object Population {
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue