mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-23 14:20:45 +00:00
wrote variable and method documentation; prepared interaction handlers for force domes for mountable (vehicle) targets
This commit is contained in:
parent
dd0f5fc928
commit
94bd315354
9 changed files with 133 additions and 36 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 _ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue