force dome is now an amenity owned by its encompassing capitol facility and has its own control agency that is aware of the faction affinity, hack state, etc. conditions that would cause it to close over or open up

This commit is contained in:
Fate-JH 2025-12-15 15:14:27 -05:00
parent 1d57cca1d3
commit 8fedd2e724
8 changed files with 354 additions and 124 deletions

View file

@ -1060,7 +1060,7 @@ class ZoningOperations(
case _ => ()
}
// capitol force dome state
if (building.IsCapitol && building.ForceDomeActive) {
if (building.IsCapitol && building.ForceDome.exists(_.Energized)) {
sendResponse(GenericObjectActionMessage(guid, 13))
}
// amenities

View file

@ -10,7 +10,6 @@ import net.psforever.objects.zones.blockmap.{BlockMapEntity, SectorGroup}
import net.psforever.objects.{ConstructionItem, PlanetSideGameObject, Player, Vehicle}
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, PlanetSideGeneratorState, Vector3}
import akka.actor.typed.scaladsl.adapter._
import net.psforever.actors.zone.building.MajorFacilityLogic
import net.psforever.objects.avatar.scoring.Kill
import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalAwareBehavior
@ -110,7 +109,6 @@ class ZoneActor(
//warp gates are controlled by game logic and are better off not restored via the database
case Some(b) =>
if ((b.Faction = PlanetSideEmpire(building.factionId)) != PlanetSideEmpire.NEUTRAL) {
b.ForceDomeActive = MajorFacilityLogic.checkForceDomeStatus(b).getOrElse(false)
b.Neighbours.getOrElse(Nil).foreach(_.Actor ! BuildingActor.AlertToFactionChange(b))
b.CaptureTerminal.collect { terminal =>
val msg = CaptureTerminalAwareBehavior.TerminalStatusChanged(terminal, isResecured = true)

View file

@ -15,7 +15,7 @@ import net.psforever.services.{InterstellarClusterService, Service}
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, PlanetSideGeneratorState}
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
/**
* A package class that conveys the important information for handling facility updates.
@ -56,99 +56,6 @@ case object MajorFacilityLogic
MajorFacilityWrapper(building, context, details.galaxyService, details.interstellarCluster)
}
/**
* Evaluate the conditions of the building
* and determine if its capitol force dome state should be updated
* to reflect the actual conditions of the base or its surrounding bases.
* If this building is considered a subcapitol facility to the zone's actual capitol facility,
* and has the capitol force dome has a dependency upon it,
* pass a message onto that facility that it should check its own state alignment.
* @param mapUpdateOnChange if `true`, dispatch a `MapUpdate` message for this building
*/
private def alignForceDomeStatus(details: BuildingWrapper, mapUpdateOnChange: Boolean = true): Behavior[Command] = {
val building = details.building
checkForceDomeStatus(building) match {
case Some(updatedStatus) if updatedStatus != building.ForceDomeActive =>
updateForceDomeStatus(details, updatedStatus, mapUpdateOnChange)
case _ => ;
}
Behaviors.same
}
/**
* Dispatch a message to update the state of the clients with the server state of the capitol force dome.
* @param updatedStatus the new capitol force dome status
* @param mapUpdateOnChange if `true`, dispatch a `MapUpdate` message for this building
*/
private def updateForceDomeStatus(
details: BuildingWrapper,
updatedStatus: Boolean,
mapUpdateOnChange: Boolean
): Unit = {
val building = details.building
val zone = building.Zone
building.ForceDomeActive = updatedStatus
zone.LocalEvents ! LocalServiceMessage(
zone.id,
LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, building.GUID, updatedStatus)
)
if (mapUpdateOnChange) {
details.context.self ! BuildingActor.MapUpdate()
}
}
/**
* The natural conditions of a facility that is not eligible for its capitol force dome to be expanded.
* The only test not employed is whether or not the target building is a capitol.
* Ommission of this condition makes this test capable of evaluating subcapitol eligibility
* for capitol force dome expansion.
* @param building the target building
* @return `true`, if the conditions for capitol force dome are not met;
* `false`, otherwise
*/
private def invalidBuildingCapitolForceDomeConditions(building: Building): Boolean = {
building.Faction == PlanetSideEmpire.NEUTRAL ||
building.NtuLevel == 0 ||
(building.Generator match {
case Some(o) => o.Condition == PlanetSideGeneratorState.Destroyed
case _ => false
})
}
/**
* If this building is a capitol major facility,
* use the faction affinity, the generator status, and the resource silo's capacitance level
* to determine if the capitol force dome should be active.
* @param building the building being evaluated
* @return the condition of the capitol force dome;
* `None`, if the facility is not a capitol building;
* `Some(true|false)` to indicate the state of the force dome
*/
def checkForceDomeStatus(building: Building): Option[Boolean] = {
if (building.IsCapitol) {
val originalStatus = building.ForceDomeActive
val faction = building.Faction
val updatedStatus = if (invalidBuildingCapitolForceDomeConditions(building)) {
false
} else {
val ownedSubCapitols = building.Neighbours(faction) match {
case Some(buildings: Set[Building]) => buildings.count { b => !invalidBuildingCapitolForceDomeConditions(b) }
case None => 0
}
if (originalStatus && ownedSubCapitols <= 1) {
false
} else if (!originalStatus && ownedSubCapitols > 1) {
true
} else {
originalStatus
}
}
Some(updatedStatus)
} else {
None
}
}
/**
* The power structure of major facilities has to be statused on the continental map
* via the state of its nanite-to-energy generator, and
@ -267,7 +174,7 @@ case object MajorFacilityLogic
}
/**
* The generator is an extrememly important amenity of a major facility
* The generator is an extremely important amenity of a major facility
* that is given its own status indicators that are apparent from the continental map
* and warning messages that are displayed to everyone who might have an interest in the that particular generator.
* @param details package class that conveys the important information
@ -314,7 +221,6 @@ case object MajorFacilityLogic
true
case Some(GeneratorControl.Event.Offline) =>
powerLost(details)
alignForceDomeStatus(details, mapUpdateOnChange = false)
val zone = building.Zone
val msg = AvatarAction.PlanetsideAttributeToAll(building.GUID, 46, 2)
building.PlayersInSOI.foreach { player =>
@ -326,7 +232,6 @@ case object MajorFacilityLogic
case Some(GeneratorControl.Event.Online) =>
// Power restored. Reactor Online. Sensors Online. Weapons Online. All systems nominal.
powerRestored(details)
alignForceDomeStatus(details, mapUpdateOnChange = false)
val events = zone.AvatarEvents
val guid = building.GUID
val msg1 = AvatarAction.PlanetsideAttributeToAll(guid, 46, 0)
@ -348,16 +253,17 @@ case object MajorFacilityLogic
): Behavior[Command] = {
if (details.asInstanceOf[MajorFacilityWrapper].hasNtuSupply) {
BuildingActor.setFactionTo(details, faction, log)
alignForceDomeStatus(details, mapUpdateOnChange = false)
val building = details.building
building.Neighbours.getOrElse(Nil).foreach { _.Actor ! BuildingActor.AlertToFactionChange(building) }
val alertMsg = BuildingActor.AlertToFactionChange(building)
building.Neighbours.getOrElse(Nil).foreach { _.Actor ! alertMsg }
building.Amenities.foreach { _.Actor ! alertMsg }
}
Behaviors.same
}
def alertToFactionChange(details: BuildingWrapper, building: Building): Behavior[Command] = {
alignForceDomeStatus(details)
val bldg = details.building
bldg.Amenities.foreach { _.Actor ! BuildingActor.AlertToFactionChange(building) } //todo map update?
//the presence of the flag means that we are involved in an ongoing llu hack
(bldg.GetFlag, bldg.CaptureTerminal) match {
case (Some(flag), Some(terminal)) if (flag.Target eq building) && flag.Faction != building.Faction =>

View file

@ -0,0 +1,313 @@
// Copyright (c) 2025 PSForever
package net.psforever.objects.serverobject.dome
import net.psforever.actors.zone.BuildingActor
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
import net.psforever.objects.serverobject.structures.{Amenity, Building, PoweredAmenityControl}
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
import net.psforever.objects.serverobject.turret.FacilityTurret
import net.psforever.packet.game.ChatMsg
import net.psforever.services.Service
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGeneratorState, Vector3}
object ForceDomeControl {
trait Command
final case object CustomExpand extends Command
final case object CustomCollapse extends Command
final case object NormalBehavior extends Command
/**
* Dispatch a message to update the state of the clients with the server state of the capitol force dome.
* @param dome force dome
* @param activationState new force dome status
*/
def ChangeDomeEnergizedState(dome: ForceDomePhysics, activationState: Boolean): Unit = {
dome.Energized = activationState
val owner = dome.Owner
val zone = owner.Zone
zone.LocalEvents ! LocalServiceMessage(
zone.id,
LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, owner.GUID, activationState)
)
}
/**
* If this building is a capitol major facility,
* use the faction affinity, the generator status, and the resource silo's capacitance level
* to determine if the capitol force dome should be active.
* @param building building being evaluated
* @param dome force dome
* @return the condition of the capitol force dome;
* `None`, if the facility is not a capitol building;
* `Some(true|false)` to indicate the state of the force dome
*/
def CheckForceDomeStatus(building: Building, dome: ForceDomePhysics): Option[Boolean] = {
if (building.IsCapitol) {
Some(
if (ForceDomeControl.InvalidBuildingCapitolForceDomeConditions(building)) {
false
} else {
building
.Neighbours(building.Faction)
.map(_.count(b => !ForceDomeControl.InvalidBuildingCapitolForceDomeConditions(b)))
.exists(_ > 1)
}
)
} else {
None
}
}
/**
* The natural conditions of a facility that is not eligible for its capitol force dome to be expanded.
* The only test not employed is whether or not the target building is a capitol.
* Omission of this condition makes this test capable of evaluating subcapitol eligibility
* for capitol force dome expansion.
* @param building target building
* @return `true`, if the conditions for capitol force dome are not met;
* `false`, otherwise
*/
def InvalidBuildingCapitolForceDomeConditions(building: Building): Boolean = {
building.Faction == PlanetSideEmpire.NEUTRAL ||
building.NtuLevel == 0 ||
building.Generator.exists(_.Condition == PlanetSideGeneratorState.Destroyed)
}
/**
* na
* @param dome force dome
* @return na
*/
def GeneralFacilityPerimeter(dome: ForceDomePhysics): List[(Vector3, Vector3)] = {
val generatorTowerCenter = dome.Position.xy
val turretPoints = dome.Owner.Amenities.filter(_.isInstanceOf[FacilityTurret]).map(_.Position.xy)
val pointsOfForceDomePerimeter = turretPoints.map { p =>
val segmentFromTowerToTurret = p - generatorTowerCenter
Vector3.Unit(segmentFromTowerToTurret) * (Vector3.Magnitude(segmentFromTowerToTurret) + 20) //todo get correct distance offset
}
pointsOfForceDomePerimeter
.flatMap { point =>
pointsOfForceDomePerimeter
.sortBy(p => Vector3.DistanceSquared(p, point))
.slice(1, 3)
.map { otherPoint =>
if (point.y > otherPoint.y || point.x < otherPoint.x) {
(point, otherPoint)
} else {
(otherPoint, point)
}
}
}
.distinct
}
def TechPlantFacilityPerimeter(dome: ForceDomePhysics): List[(Vector3, Vector3)] = {
val generatorTowerCenter = dome.Position.xy
val turretPoints = dome.Owner.Amenities.filter(_.isInstanceOf[FacilityTurret]).map(_.Position.xy)
val organizedByClosestToGarage = dome
.Owner
.Amenities
.find(_.Definition.Name.equals("gr_door_garage_ext"))
.map { garage =>
val doorPosition = garage.Position.xy
turretPoints.sortBy(point => Vector3.DistanceSquared(doorPosition, point))
}
.getOrElse(List[Vector3]())
//val turretPoints = dome.Owner.Amenities.filter(_.isInstanceOf[FacilityTurret]).map(_.Position.xy)
val pointsOfForceDomePerimeter = turretPoints.map { p =>
val segmentFromTowerToTurret = p - generatorTowerCenter
Vector3.Unit(segmentFromTowerToTurret) * (Vector3.Magnitude(segmentFromTowerToTurret) + 20) //todo get correct distance offset
}
Nil
}
/**
* na
* @param building target building
* @param state na
*/
def CustomDomeStateEnforcedMessage(
building: Building,
state: Boolean
): Unit = {
val events = building.Zone.LocalEvents
val message = LocalAction.SendResponse(ChatMsg(
ChatMessageType.UNK_227,
s"Capitol force dome state change was suppressed. ${building.Name} will remain ${if (state) "enveloped" else "exposed"}."
))
building.PlayersInSOI.foreach { player =>
events ! LocalServiceMessage(player.Name, message)
}
}
/**
* na
* @param building target building
*/
def NormalDomeStateMessage(building: Building): Unit = {
val events = building.Zone.LocalEvents
val message = LocalAction.SendResponse(ChatMsg(
ChatMessageType.UNK_227,
"Expected capitol force dome state change will resume."
))
building.PlayersInSOI.foreach { player =>
events ! LocalServiceMessage(player.Name, message)
}
}
}
/**
* An `Actor` that handles messages being dispatched to a specific capitol facility's force dome.
* @param dome the `ForceDomePhysics` object being governed
*/
class ForceDomeControl(dome: ForceDomePhysics)
extends PoweredAmenityControl
with CaptureTerminalAwareBehavior
with FactionAffinityBehavior.Check {
def CaptureTerminalAwareObject: Amenity with CaptureTerminalAware = dome
def FactionObject: FactionAffinity = dome
private var perimeterSegments: List[(Vector3, Vector3)] = Nil
private lazy val domeOwnerAsABuilding = dome.Owner.asInstanceOf[Building]
private var customState: Option[Boolean] = None
def commonBehavior: Receive = checkBehavior
.orElse {
case Service.Startup() =>
setupPerimeter()
case ForceDomeControl.CustomExpand
if !dome.Energized && (customState.isEmpty || customState.contains(false)) =>
customState = Some(true)
ForceDomeControl.CustomDomeStateEnforcedMessage(domeOwnerAsABuilding, state = true)
ForceDomeControl.ChangeDomeEnergizedState(dome, activationState = true)
case ForceDomeControl.CustomExpand
if customState.isEmpty =>
customState = Some(true)
ForceDomeControl.CustomDomeStateEnforcedMessage(domeOwnerAsABuilding, state = true)
case ForceDomeControl.CustomCollapse
if dome.Energized && (customState.isEmpty || customState.contains(true)) =>
customState = Some(false)
ForceDomeControl.CustomDomeStateEnforcedMessage(domeOwnerAsABuilding, state = false)
ForceDomeControl.ChangeDomeEnergizedState(dome, activationState = false)
case ForceDomeControl.CustomCollapse
if customState.isEmpty =>
customState = Some(false)
ForceDomeControl.CustomDomeStateEnforcedMessage(domeOwnerAsABuilding, state = false)
case ForceDomeControl.NormalBehavior
if customState.nonEmpty =>
customState = None
ForceDomeControl.NormalDomeStateMessage(domeOwnerAsABuilding)
alignForceDomeStatusAndUpdate(domeOwnerAsABuilding)
}
def poweredStateLogic: Receive = {
commonBehavior
.orElse(captureTerminalAwareBehaviour)
.orElse {
case BuildingActor.AlertToFactionChange(_) =>
blockedByCustomStateOr(alignForceDomeStatusAndUpdate, domeOwnerAsABuilding)
case _ => ()
}
}
def unpoweredStateLogic: Receive = {
commonBehavior
.orElse {
case _ => ()
}
}
def powerTurnOffCallback() : Unit = {
if (dome.Energized && customState.isEmpty) {
ForceDomeControl.ChangeDomeEnergizedState(dome,activationState = false)
}
}
def powerTurnOnCallback() : Unit = {
blockedByCustomStateOr(alignForceDomeStatus, domeOwnerAsABuilding)
}
override protected def captureTerminalIsResecured(terminal: CaptureTerminal): Unit = {
super.captureTerminalIsResecured(terminal)
blockedByCustomStateOr(alignForceDomeStatus, domeOwnerAsABuilding)
}
override protected def captureTerminalIsHacked(terminal: CaptureTerminal): Unit = {
super.captureTerminalIsHacked(terminal)
if (dome.Energized && customState.isEmpty) {
ForceDomeControl.ChangeDomeEnergizedState(dome, activationState = false)
}
}
private def setupPerimeter(): Unit = {
//todo tech plants have an indent
if (perimeterSegments.isEmpty) {
perimeterSegments = ForceDomeControl.GeneralFacilityPerimeter(dome)
}
}
/**
* na
* @param func function to run if not blocked
* @param building facility to operate upon (parameter to `func`)
* @return next behavior for an actor state
*/
private def blockedByCustomStateOr(func: Building => Unit, building: Building): Unit = {
customState match {
case None =>
func(building)
case Some(state) =>
ForceDomeControl.CustomDomeStateEnforcedMessage(building, state)
}
}
/**
* Evaluate the conditions of the building
* and determine if its capitol force dome state should be updated
* to reflect the actual conditions of the base or its surrounding bases.
* If this building is considered a subcapitol facility to the zone's actual capitol facility,
* and has the capitol force dome has a dependency upon it,
* pass a message onto that facility that it should check its own state alignment.
* @param building the building being evaluated
*/
private def alignForceDomeStatusAndUpdate(building: Building): Unit = {
ForceDomeControl.CheckForceDomeStatus(building, dome).foreach {
updatedStatus =>
if (updatedStatus != dome.Energized) {
ForceDomeControl.ChangeDomeEnergizedState(dome, updatedStatus)
dome.Owner.Actor ! BuildingActor.MapUpdate()
}
}
}
/**
* Evaluate the conditions of the building
* and determine if its capitol force dome state should be updated
* to reflect the actual conditions of the base or its surrounding bases.
* If this building is considered a subcapitol facility to the zone's actual capitol facility,
* and has the capitol force dome has a dependency upon it,
* pass a message onto that facility that it should check its own state alignment.
* @param building the building being evaluated
*/
private def alignForceDomeStatus(building: Building): Unit = {
ForceDomeControl.CheckForceDomeStatus(building, dome).foreach {
updatedStatus =>
if (updatedStatus != dome.Energized) {
ForceDomeControl.ChangeDomeEnergizedState(dome, updatedStatus)
}
}
}
}

View file

@ -2,10 +2,12 @@
package net.psforever.objects.serverobject.dome
import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalAware
import net.psforever.types.Vector3
class ForceDomePhysics(private val cfddef: ForceDomeDefinition)
extends Amenity {
extends Amenity
with CaptureTerminalAware {
private var energized: Boolean = false
def Energized: Boolean = energized
@ -23,18 +25,18 @@ object ForceDomePhysics {
/**
* Instantiate and configure a `CapitolForceDome` object.
* @param pos positon of the object in the zone's coordinate system
* @param pos position of the object in the zone's coordinate system
* @param fddef specific type of force dome
* @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 `CapitolForceDome` object
*/
def Constructor(pos: Vector3)(id: Int, context: ActorContext): ForceDomePhysics = {
//import akka.actor.Props
import net.psforever.objects.GlobalDefinitions
def Constructor(pos: Vector3, fddef: ForceDomeDefinition)(id: Int, context: ActorContext): ForceDomePhysics = {
import akka.actor.Props
val obj = new ForceDomePhysics(GlobalDefinitions.force_dome_generator)
val obj = new ForceDomePhysics(fddef)
obj.Position = pos
//obj.Actor = context.actorOf(Props(classOf[null], obj), s"${GlobalDefinitions.door.Name}_$id")
obj.Actor = context.actorOf(Props(classOf[ForceDomeControl], obj), name = s"${fddef.Name}_$id")
obj
}
}

View file

@ -15,6 +15,7 @@ import net.psforever.packet.game.{Additional3, BuildingInfoUpdateMessage, Densit
import net.psforever.types._
import scalax.collection.{Graph, GraphEdge}
import akka.actor.typed.scaladsl.adapter._
import net.psforever.objects.serverobject.dome.ForceDomePhysics
import net.psforever.objects.serverobject.llu.{CaptureFlag, CaptureFlagSocket}
import net.psforever.objects.serverobject.structures.participation.{MajorFacilityHackParticipation, NoParticipation, ParticipationLogic, TowerHackParticipation}
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
@ -32,7 +33,6 @@ class Building(
private var faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
private var playersInSOI: List[Player] = List.empty
private var forceDomeActive: Boolean = false
private var participationFunc: ParticipationLogic = NoParticipation
var virusId: Long = 8 // 8 default = no virus
var virusInstalledBy: Option[Int] = None // faction id
@ -59,11 +59,6 @@ class Building(
case None => false
}
}
def ForceDomeActive: Boolean = forceDomeActive
def ForceDomeActive_=(activated: Boolean): Boolean = {
forceDomeActive = activated
forceDomeActive
}
def Faction: PlanetSideEmpire.Value = faction
@ -108,6 +103,13 @@ class Building(
}
}
def ForceDome: Option[ForceDomePhysics] = {
Amenities.find(_.isInstanceOf[ForceDomePhysics]) match {
case Some(out: ForceDomePhysics) => Some(out)
case _ => None
}
}
def NtuSource: Option[NtuContainer] = {
Amenities.find(_.isInstanceOf[NtuContainer]) match {
case Some(o: NtuContainer) => Some(o)
@ -223,6 +225,7 @@ class Building(
else {
(virusId.toInt, Some(Additional3(inform_defenders=true, virusInstalledBy.getOrElse(3))))
}
val forceDomeActive = ForceDome.exists(_.Energized)
BuildingInfoUpdateMessage(
Zone.Number,

View file

@ -40,6 +40,7 @@ import net.psforever.objects.geometry.d3.VolumetricGeometry
import net.psforever.objects.guid.pool.NumberPool
import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.serverobject.dome.{ForceDomeDefinition, ForceDomePhysics}
import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.serverobject.environment.EnvironmentAttribute
import net.psforever.objects.serverobject.interior.{InteriorAware, Sidedness}
@ -1638,6 +1639,13 @@ object Zone {
case painbox: Painbox =>
painbox.Actor ! Service.Startup()
}
//capitol facilities have force domes
buildings.values
.flatMap(_.Amenities.filter(_.Definition.isInstanceOf[ForceDomeDefinition]))
.collect {
case obj: ForceDomePhysics =>
obj.Actor ! Service.Startup()
}
//the orbital_buildings in sanctuary zones have to establish their shuttle routes
map.shuttleBays
.map {

View file

@ -11,7 +11,7 @@ import io.circe.parser._
import net.psforever.objects.{GlobalDefinitions, LocalLockerItem, LocalProjectile}
import net.psforever.objects.definition.BasicDefinition
import net.psforever.objects.guid.selector.{NumberSelector, RandomSelector, SpecificSelector}
import net.psforever.objects.serverobject.dome.ForceDomePhysics
import net.psforever.objects.serverobject.dome.{ForceDomeDefinition, ForceDomePhysics}
import net.psforever.objects.serverobject.doors.{Door, DoorDefinition, SpawnTubeDoor}
import net.psforever.objects.serverobject.generator.Generator
import net.psforever.objects.serverobject.llu.{CaptureFlagSocket, CaptureFlagSocketDefinition}
@ -385,7 +385,7 @@ object Zones {
None,
turretWeaponGuid
)
//force dome physics object are not owned
//force dome physics objects have no owner
//for our benefit, we can attach them as amenities to the zone's capitol facility
zoneObjects
.find { obj => forceDomeTypes.contains(obj.objectType) }
@ -393,12 +393,12 @@ object Zones {
structures
.find { structure => Building.Capitols.contains(structure.objectName) }
.foreach { capitol =>
zoneMap
.addLocalObject(
forceDome.guid,
ForceDomePhysics.Constructor(forceDome.position),
owningBuildingGuid = capitol.guid
)
val definition = DefinitionUtil.fromString(forceDome.objectType).asInstanceOf[ForceDomeDefinition]
zoneMap.addLocalObject(
forceDome.guid,
ForceDomePhysics.Constructor(forceDome.position, definition),
owningBuildingGuid = capitol.guid
)
}
}