wrote variable and method documentation; prepared interaction handlers for force domes for mountable (vehicle) targets

This commit is contained in:
Fate-JH 2025-12-23 14:51:25 -05:00
parent dd0f5fc928
commit 94bd315354
9 changed files with 133 additions and 36 deletions

View file

@ -40,6 +40,7 @@ class Player(var avatar: Avatar)
with InteriorAwareFromInteraction
with AuraContainer
with MountableEntity {
interaction(new InteractWithForceDomeProtection())
interaction(environment.interaction.InteractWithEnvironment(Seq(
new WithEntrance(),
new WithWater(avatar.name),
@ -51,7 +52,6 @@ class Player(var avatar: Avatar)
interaction(new InteractWithMines(range = 10, TriggerOnPlayerRule))
interaction(new InteractWithTurrets())
interaction(new InteractWithRadiationClouds(range = 10f, Some(this)))
interaction(new InteractWithForceDomeProtection())
private var backpack: Boolean = false
private var released: Boolean = false

View file

@ -24,7 +24,9 @@ class InteractWithForceDomeProtection
private var protectedBy: Option[ForceDomePhysics] = None
/**
* na
* If the target is protected, do conditions allow it to remain protected?
* If the target was vulnerable, can it be protected?
* Five second pause between evaluations (0-3, wait; 4, test).
* @see `ForceDomeControl.TargetUnderForceDome`
* @param sector the portion of the block map being tested
* @param target the fixed element in this test
@ -70,19 +72,24 @@ class InteractWithForceDomeProtection
ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(target, dome, maxDistance = 0f)
}
.map { dome =>
protectedBy = Some(dome)
target.Actor ! Damageable.MakeInvulnerable
applyProtection(target, dome)
dome
}
}
protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
protectedBy = Some(dome)
target.Actor ! Damageable.MakeInvulnerable
}
/**
* na
* No longer invulnerable (if ever).
* Set the counter to force a reevaluation of the vulnerability state next turn.
* @see `Damageable.MakeVulnerable`
* @param target the fixed element in this test
*/
def resetInteraction(target: InteractsWithZone): Unit = {
protectSkipCounter = 0
protectSkipCounter = 5
protectedBy = None
target.Actor ! Damageable.MakeVulnerable
}

View file

@ -157,6 +157,8 @@ object ForceDomeControl {
* 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 facility with `dome`
* @param dome force dome
* @return current state of the capitol force dome
*/
def AlignForceDomeStatusAndUpdate(building: Building, dome: ForceDomePhysics): Boolean = {
val energizedState = dome.Energized
@ -182,6 +184,8 @@ object ForceDomeControl {
* 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 facility with `dome`
* @param dome force dome
* @return current state of the capitol force dome
*/
private def AlignForceDomeStatus(building: Building, dome: ForceDomePhysics): Boolean = {
val energizedState = dome.Energized
@ -202,7 +206,8 @@ object ForceDomeControl {
* This is the usual fate of opponents upon it being expanded (energized).
* @see `Zone.serverSideDamage`
* @param dome force dome
* @return a list of affected entities
* @param perimeter ground-level perimeter of the force dome is defined by these segments (as vertex pairs)
* @return list of affected entities
*/
def ForceDomeKills(dome: ForceDomePhysics, perimeter: List[(Vector3, Vector3)]): List[PlanetSideServerObject] = {
Zone.serverSideDamage(
@ -222,9 +227,9 @@ object ForceDomeControl {
* @return a `DamageInteraction` object
*/
private def makesContactWithForceDome(
source: PlanetSideGameObject with FactionAffinity with Vitality,
target: PlanetSideGameObject with FactionAffinity with Vitality
): DamageInteraction = {
source: PlanetSideGameObject with FactionAffinity with Vitality,
target: PlanetSideGameObject with FactionAffinity with Vitality
): DamageInteraction = {
DamageInteraction(
SourceEntry(target),
ForceDomeExposure(SourceEntry(source)),
@ -233,7 +238,11 @@ object ForceDomeControl {
}
/**
* na
* To be considered within a force dome, a target entity must satisfy two orientations
* where the second condition is one of two qualifications:
* 1. within an angular perimeter boundary, and
* 2a. below the base coordinate of the force dome or
* 2b. within a region above the base of the force dome represented by a literal "dome" (half of a sphere).
* @see `Zone.distanceCheck`
* @param segments ground-level perimeter of the force dome is defined by these segments (as vertex pairs)
* @param obj1 a game entity, should be the force dome
@ -470,9 +479,6 @@ class ForceDomeControl(dome: ForceDomePhysics)
//dome activating
context.system.scheduler.scheduleOnce(delay = 1500 milliseconds, self, ForceDomeControl.Purge)
context.system.scheduler.scheduleOnce(delay = 4000 milliseconds, self, ForceDomeControl.ApplyProtection)
} else if (oldState && !newState) {
//dome de-activating
dome.Zone.blockMap.removeFrom(dome)
}
newState
case Some(state) =>

View file

@ -26,19 +26,16 @@ class ForceDomeDefinition(objectId: Int)
object ForceDomeDefinition {
/**
* na
* @param o na
* @return na
* Transform a capitol force dome into a bounded geometric representation.
* @param o any entity from which to produce a geometric representation
* @return geometric representation
*/
def representBy(o: Any): VolumetricGeometry = {
import net.psforever.objects.geometry.GeometryForm.invalidPoint
o match {
case fdp: ForceDomePhysics =>
Sphere(fdp.Position, fdp.Definition.UseRadius)
case s: SourceEntry =>
Sphere(s.Position, s.Definition.UseRadius)
case _ =>
Sphere(invalidPoint, 1f)
net.psforever.objects.geometry.GeometryForm.invalidPoint
}
}
}

View file

@ -8,10 +8,20 @@ import net.psforever.types.Vector3
class ForceDomePhysics(private val cfddef: ForceDomeDefinition)
extends Amenity
with CaptureTerminalAware {
/** whether the dome is active or not */
private var energized: Boolean = false
/** defined perimeter of this force dome on the floor;
* the walls created by this perimeter are angled inwards towards the facility, but that's not a consideration */
private var perimeter: List[(Vector3, Vector3)] = List()
override def Position: Vector3 = Owner.Position
override def Position_=(vec: Vector3): Vector3 = Owner.Position
override def Orientation: Vector3 = Owner.Orientation
override def Orientation_=(vec: Vector3): Vector3 = Owner.Orientation
def Energized: Boolean = energized
def Energized_=(state: Boolean): Boolean = {
@ -34,17 +44,15 @@ object ForceDomePhysics {
/**
* Instantiate and configure a `CapitolForceDome` object.
* @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, fddef: ForceDomeDefinition)(id: Int, context: ActorContext): ForceDomePhysics = {
def Constructor(fddef: ForceDomeDefinition)(id: Int, context: ActorContext): ForceDomePhysics = {
import akka.actor.Props
val obj = new ForceDomePhysics(fddef)
obj.Position = pos
obj.Actor = context.actorOf(Props(classOf[ForceDomeControl], obj), name = s"${fddef.Name}_$id")
obj
}

View file

@ -0,0 +1,36 @@
// Copyright (c) 2025 PSForever
package net.psforever.objects.serverobject.mount
import net.psforever.objects.avatar.interaction.InteractWithForceDomeProtection
import net.psforever.objects.serverobject.damage.Damageable
import net.psforever.objects.serverobject.dome.ForceDomePhysics
import net.psforever.objects.zones.InteractsWithZone
class InteractWithForceDomeProtectionSeatedInEntity
extends InteractWithForceDomeProtection {
override def range: Float = 30f
override protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
super.applyProtection(target, dome)
target
.asInstanceOf[Mountable]
.Seats
.values
.flatMap(_.occupants)
.foreach { occupant =>
occupant.Actor ! Damageable.MakeInvulnerable
}
}
override def resetInteraction(target: InteractsWithZone): Unit = {
super.resetInteraction(target)
target
.asInstanceOf[Mountable]
.Seats
.values
.flatMap(_.occupants)
.foreach { occupant =>
occupant.Actor ! Damageable.MakeVulnerable
}
}
}

View file

@ -0,0 +1,49 @@
// Copyright (c) 2025 PSForever
package net.psforever.objects.vehicles.interaction
import net.psforever.objects.Vehicle
import net.psforever.objects.avatar.interaction.{ForceZoneProtection, InteractWithForceDomeProtection}
import net.psforever.objects.serverobject.dome.ForceDomePhysics
import net.psforever.objects.serverobject.mount.InteractWithForceDomeProtectionSeatedInEntity
import net.psforever.objects.zones.InteractsWithZone
class InteractWithForceDomeProtectionSeatedInVehicle
extends InteractWithForceDomeProtectionSeatedInEntity {
override protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
super.applyProtection(target, dome)
target
.asInstanceOf[Vehicle]
.CargoHolds
.values
.flatMap(_.occupants)
.foreach { vehicle =>
vehicle
.interaction()
.find(_.Type == ForceZoneProtection)
.foreach {
case interaction: InteractWithForceDomeProtection =>
interaction.applyProtection(vehicle, dome)
case _ => ()
}
}
}
override def resetInteraction(target: InteractsWithZone): Unit = {
super.resetInteraction(target)
target
.asInstanceOf[Vehicle]
.CargoHolds
.values
.flatMap(_.occupants)
.foreach { vehicle =>
vehicle
.interaction()
.find(_.Type == ForceZoneProtection)
.foreach {
case interaction: InteractWithForceDomeProtection =>
interaction.resetInteraction(vehicle)
case _ => ()
}
}
}
}

View file

@ -22,25 +22,19 @@ final case class ForceDomeExposure(field: SourceEntry)
}
/**
* Want to blame the capitol facility that is being protected.
* Blame the capitol facility that is being protected.
*/
override def attribution: Int = field match {
case a: AmenitySource => a.installation.Definition.ObjectId
case _ => field.Definition.ObjectId
}
/**
* A direct connection to the damage information, numbers and properties.
*/
override def source: DamageProperties = ForceDomeExposure.damageProperties
/**
* The functionality that is necessary for interaction of a vital game object with the rest of the hostile game world.
*/
override def damageModel: DamageAndResistance = ForceDomeExposure.drm
/**
* The person to be blamed for this.
* No one person will be blamed for this.
*/
override def adversary: Option[SourceEntry] = None
}

View file

@ -392,12 +392,12 @@ object Zones {
.foreach { forceDome =>
structures
.find { structure => Building.Capitols.contains(structure.objectName) }
.foreach { capitol =>
.foreach { structure =>
val definition = DefinitionUtil.fromString(forceDome.objectType).asInstanceOf[ForceDomeDefinition]
zoneMap.addLocalObject(
forceDome.guid,
ForceDomePhysics.Constructor(forceDome.position, definition),
owningBuildingGuid = capitol.guid
ForceDomePhysics.Constructor(definition),
owningBuildingGuid = structure.guid
)
}
}