mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-20 02:54:46 +00:00
removed three too-specific fields on the door's definition, resulting in nontrivial rewrites that resulted in all amenities being able to project an environment field onto the block map, to do with whatever it needs
This commit is contained in:
parent
84b3d2297a
commit
86acd94fd7
|
|
@ -1515,7 +1515,7 @@ private[support] class WeaponAndProjectileOperations(
|
|||
origin,
|
||||
hitPosition,
|
||||
door.Position,
|
||||
door.Definition.geometryInteractionRadius.get + 0.1f
|
||||
door.Definition.UseRadius + 0.1f
|
||||
)
|
||||
(door, intersectTest)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,18 +162,10 @@ object SpawnPoint {
|
|||
}
|
||||
|
||||
trait SpawnPointDefinition {
|
||||
private var radius: Float = 0f //m
|
||||
private var delay: Long = 0 //s
|
||||
private var noWarp: Option[mutable.Set[VehicleDefinition]] = None
|
||||
private var spawningFunc: (SpawnPoint, PlanetSideGameObject) => (Vector3, Vector3) = SpawnPoint.Default
|
||||
|
||||
def UseRadius: Float = radius
|
||||
|
||||
def UseRadius_=(rad: Float): Float = {
|
||||
radius = rad
|
||||
UseRadius
|
||||
}
|
||||
|
||||
def Delay: Long = delay
|
||||
|
||||
def Delay_=(toDelay: Long): Long = {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
|||
import net.psforever.objects.serverobject.interior.{InteriorAwareFromInteraction, Sidedness}
|
||||
import net.psforever.objects.serverobject.structures.AmenityOwner
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vehicles.interaction.{WithEntranceInVehicle, WithLava, WithWater}
|
||||
import net.psforever.objects.vehicles.interaction.{WithLava, WithWater}
|
||||
import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.vital.resolution.DamageResistanceModel
|
||||
|
|
|
|||
|
|
@ -20,13 +20,23 @@ import net.psforever.types.OxygenState
|
|||
* So long as it is an `ObjectCreatePacket`, those methods can be called correctly for a game object of the desired type.
|
||||
* @param objectId the object's identifier number
|
||||
*/
|
||||
abstract class ObjectDefinition(private val objectId: Int) extends BasicDefinition {
|
||||
abstract class ObjectDefinition(private val objectId: Int)
|
||||
extends BasicDefinition {
|
||||
var registerAs: String = "generic"
|
||||
|
||||
/** a data converter for this type of object */
|
||||
protected var packet: PacketConverter = new ObjectCreateConverter[PlanetSideGameObject]() {}
|
||||
Name = "object_definition"
|
||||
|
||||
private var useRadius: Float = 0f
|
||||
|
||||
def UseRadius: Float = useRadius
|
||||
|
||||
def UseRadius_=(radius: Float): Float = {
|
||||
useRadius = radius
|
||||
UseRadius
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the conversion object.
|
||||
* @return
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ object GeometryForm {
|
|||
*/
|
||||
def representByCylinder(radius: Float, height: Float)(o: Any): VolumetricGeometry = {
|
||||
o match {
|
||||
case p: PlanetSideGameObject => Cylinder(p.Position, Vector3.relativeUp(p.Orientation), radius, height)
|
||||
case s: SourceEntry => Cylinder(s.Position, Vector3.relativeUp(s.Orientation), radius, height)
|
||||
case p: PlanetSideGameObject => Cylinder(p.Position, Vector3.relativeUp(p.Orientation), radius, math.abs(height))
|
||||
case s: SourceEntry => Cylinder(s.Position, Vector3.relativeUp(s.Orientation), radius, math.abs(height))
|
||||
case _ => invalidCylinder
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,13 @@ package net.psforever.objects.geometry
|
|||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.geometry.d2.Rectangle
|
||||
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.environment.EnvironmentCollision
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
case class VolumetricEnvironmentCollision(door: Door)
|
||||
final case class VolumetricEnvironmentCollision(g: VolumetricGeometry)
|
||||
extends EnvironmentCollision {
|
||||
private lazy val geometry = door.Definition.Geometry.apply(door)
|
||||
private lazy val bound: Rectangle = {
|
||||
val g = geometry
|
||||
Rectangle(
|
||||
g.pointOnOutside(Vector3(0, 1,0)).y,
|
||||
g.pointOnOutside(Vector3(-1,0,0)).x,
|
||||
|
|
@ -22,12 +19,12 @@ case class VolumetricEnvironmentCollision(door: Door)
|
|||
)
|
||||
}
|
||||
|
||||
def Geometry: VolumetricGeometry = geometry
|
||||
def Geometry: VolumetricGeometry = g
|
||||
|
||||
def altitude: Float = geometry.pointOnOutside(Vector3(0,0,1)).z
|
||||
def altitude: Float = g.pointOnOutside(Vector3(0,0,1)).z
|
||||
|
||||
def testInteraction(obj: PlanetSideGameObject, varDepth: Float): Boolean = {
|
||||
Zone.distanceCheck(obj.Definition.Geometry(obj), geometry) <= varDepth
|
||||
Zone.distanceCheck(obj.Definition.Geometry(obj), g) <= varDepth
|
||||
}
|
||||
|
||||
def bounding: Rectangle = bound
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import net.psforever.objects.avatar.Certification
|
|||
import net.psforever.objects.equipment.EffectTarget
|
||||
import net.psforever.objects.geometry.GeometryForm
|
||||
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||
import net.psforever.objects.serverobject.doors.InteriorDoorField
|
||||
import net.psforever.objects.serverobject.mount.{MountInfo, SeatDefinition}
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPadDefinition
|
||||
import net.psforever.objects.serverobject.structures.AutoRepairStats
|
||||
|
|
@ -601,10 +602,12 @@ object GlobalDefinitionsMiscellaneous {
|
|||
amp_cap_door.Name = "amp_cap_door"
|
||||
|
||||
ancient_door.Name = "ancient_door"
|
||||
ancient_door.geometryInteractionRadius = Some(1)
|
||||
ancient_door.UseRadius = 1f
|
||||
//ancient_door.environmentField = InteriorDoorField()
|
||||
|
||||
ancient_garage_door.Name = "ancient_garage_door"
|
||||
ancient_garage_door.geometryInteractionRadius = Some(1)
|
||||
ancient_garage_door.UseRadius = 1f
|
||||
//ancient_garage_door.environmentField = InteriorDoorField()
|
||||
|
||||
cryo_med_door.Name = "cryo_med_door"
|
||||
|
||||
|
|
@ -648,14 +651,14 @@ object GlobalDefinitionsMiscellaneous {
|
|||
gr_door_airlock.Name = "gr_door_airlock"
|
||||
|
||||
gr_door_ext.Name = "gr_door_ext"
|
||||
gr_door_ext.geometryInteractionRadius = Some(1.9f)
|
||||
gr_door_ext.UseRadius = 1.9f
|
||||
gr_door_ext.environmentField = InteriorDoorField()
|
||||
|
||||
gr_door_garage_ext.Name = "gr_door_garage_ext"
|
||||
gr_door_garage_ext.UseRadius = 11f
|
||||
gr_door_garage_ext.initialOpeningDistance = 8f
|
||||
gr_door_garage_ext.continuousOpenDistance = 9f
|
||||
gr_door_garage_ext.geometryInteractionRadius = Some(11)
|
||||
gr_door_garage_ext.geometryInteractionHeight = Some(-11)
|
||||
gr_door_garage_ext.geometryInteractionCenterOn = true
|
||||
gr_door_garage_ext.environmentField = InteriorDoorField(Some(-11), centerOn = true)
|
||||
|
||||
gr_door_garage_int.Name = "gr_door_garage_int"
|
||||
gr_door_garage_int.initialOpeningDistance = 8f
|
||||
|
|
@ -664,15 +667,18 @@ object GlobalDefinitionsMiscellaneous {
|
|||
gr_door_int.Name = "gr_door_int"
|
||||
|
||||
gr_door_main.Name = "gr_door_main"
|
||||
gr_door_main.geometryInteractionRadius = Some(2.75f)
|
||||
gr_door_main.UseRadius = 2.75f
|
||||
gr_door_main.environmentField = InteriorDoorField()
|
||||
|
||||
gr_door_mb_ext.Name = "gr_door_mb_ext"
|
||||
gr_door_mb_ext.geometryInteractionRadius = Some(2)
|
||||
gr_door_mb_ext.UseRadius = 2f
|
||||
gr_door_mb_ext.environmentField = InteriorDoorField()
|
||||
|
||||
gr_door_mb_int.Name = "gr_door_mb_int"
|
||||
|
||||
gr_door_mb_lrg.Name = "gr_door_mb_lrg"
|
||||
gr_door_mb_lrg.geometryInteractionRadius = Some(2.5f)
|
||||
gr_door_mb_lrg.UseRadius = 2.5f
|
||||
gr_door_mb_lrg.environmentField = InteriorDoorField()
|
||||
|
||||
gr_door_mb_obsd.Name = "gr_door_mb_obsd"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,22 @@ package net.psforever.objects.serverobject.doors
|
|||
|
||||
import net.psforever.objects.geometry.GeometryForm
|
||||
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||
import net.psforever.objects.serverobject.structures.AmenityDefinition
|
||||
import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, EnvironmentTrait, PieceOfEnvironment}
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, AmenityDefinition, CreateEnvironmentField}
|
||||
|
||||
final case class InteriorDoorField(
|
||||
cylinderHeight: Option[Float] = None,
|
||||
centerOn: Boolean = false
|
||||
) extends CreateEnvironmentField {
|
||||
def attribute: EnvironmentTrait = EnvironmentAttribute.InteriorField
|
||||
|
||||
def create(obj: Amenity): PieceOfEnvironment = {
|
||||
obj match {
|
||||
case door: Door => InteriorDoorPassage(door, cylinderHeight, centerOn)
|
||||
case _ => throw new IllegalArgumentException("expecting door")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The definition for any `Door`.
|
||||
|
|
@ -17,17 +32,5 @@ class DoorDefinition(objectId: Int)
|
|||
/** range within which the door must detect a target player to remain open */
|
||||
var continuousOpenDistance: Float = 5.05f
|
||||
|
||||
var geometryInteractionRadius: Option[Float] = None
|
||||
var geometryInteractionHeight: Option[Float] = None
|
||||
var geometryInteractionCenterOn: Boolean = false
|
||||
|
||||
override def Geometry: Any => VolumetricGeometry = {
|
||||
(geometryInteractionRadius, geometryInteractionHeight, geometryInteractionCenterOn) match {
|
||||
case (Some(r), Some(h), false) => GeometryForm.representByCylinder(r, h)
|
||||
case (Some(r), Some(h), true) => GeometryForm.representByRaisedCylinder(r, h)
|
||||
case (Some(r), None, false) => GeometryForm.representBySphereOnBase(r)
|
||||
case (Some(r), None, true) => GeometryForm.representBySphere(r)
|
||||
case _ => super.Geometry
|
||||
}
|
||||
}
|
||||
override def Geometry: Any => VolumetricGeometry = GeometryForm.representBySphere(UseRadius)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.objects.serverobject.doors
|
||||
|
||||
import net.psforever.objects.geometry.VolumetricEnvironmentCollision
|
||||
import net.psforever.objects.geometry.{GeometryForm, VolumetricEnvironmentCollision}
|
||||
import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, EnvironmentCollision, EnvironmentTrait, PieceOfEnvironment}
|
||||
|
||||
final case class InteriorDoorPassage(door: Door)
|
||||
final case class InteriorDoorPassage(
|
||||
door: Door,
|
||||
cylinderHeight: Option[Float] = None,
|
||||
centerOn: Boolean = false
|
||||
)
|
||||
extends PieceOfEnvironment {
|
||||
assert(door.Definition.geometryInteractionRadius.nonEmpty, s"door ${door.GUID} needs an interaction radius to be volumetric")
|
||||
//assert(door.Outwards != Vector3.Zero, s"door ${door.GUID} does not have an outwards direction")
|
||||
assert(door.Definition.UseRadius > 0f, s"door ${door.GUID} needs an interaction radius to be positive")
|
||||
private lazy val collisionObject = {
|
||||
val radius = door.Definition.UseRadius
|
||||
val g = (cylinderHeight, centerOn) match {
|
||||
case (Some(h), false) => GeometryForm.representByCylinder(radius, h) _
|
||||
case (Some(h), true) => GeometryForm.representByRaisedCylinder(radius, h) _
|
||||
case (None, false) => GeometryForm.representBySphereOnBase(radius) _
|
||||
case _ => GeometryForm.representBySphere(radius) _
|
||||
}
|
||||
VolumetricEnvironmentCollision(g.apply(door))
|
||||
}
|
||||
|
||||
/** a general description of this environment */
|
||||
override def attribute: EnvironmentTrait = EnvironmentAttribute.InteriorField
|
||||
|
||||
/** a special representation of the region that qualifies as "this environment" */
|
||||
override def collision: EnvironmentCollision = VolumetricEnvironmentCollision(door)
|
||||
override def collision: EnvironmentCollision = collisionObject
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,25 @@
|
|||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.environment.{EnvironmentTrait, PieceOfEnvironment}
|
||||
import net.psforever.objects.vital.damage.DamageCalculations
|
||||
import net.psforever.objects.vital._
|
||||
import net.psforever.objects.vital.resistance.ResistanceProfileMutators
|
||||
import net.psforever.objects.vital.resolution.DamageResistanceModel
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
final case class AutoRepairStats(amount: Float, start: Long, repeat: Long, drain: Float)
|
||||
|
||||
trait CreateEnvironmentField {
|
||||
//todo a way to probe for this property from create(...)'s output
|
||||
def attribute: EnvironmentTrait
|
||||
|
||||
def create(@unused obj: Amenity): PieceOfEnvironment
|
||||
}
|
||||
|
||||
abstract class AmenityDefinition(objectId: Int)
|
||||
extends ObjectDefinition(objectId)
|
||||
extends ObjectDefinition(objectId)
|
||||
with ResistanceProfileMutators
|
||||
with DamageResistanceModel
|
||||
with VitalityDefinition {
|
||||
|
|
@ -21,10 +31,23 @@ abstract class AmenityDefinition(objectId: Int)
|
|||
|
||||
var autoRepair: Option[AutoRepairStats] = None
|
||||
|
||||
var fields: Seq[CreateEnvironmentField] = Seq()
|
||||
|
||||
def autoRepair_=(auto: AutoRepairStats): Option[AutoRepairStats] = {
|
||||
autoRepair = Some(auto)
|
||||
autoRepair
|
||||
}
|
||||
|
||||
def hasAutoRepair: Boolean = autoRepair.nonEmpty
|
||||
|
||||
def environmentField: Seq[CreateEnvironmentField] = fields
|
||||
|
||||
def environmentField_=(theField: CreateEnvironmentField): Seq[CreateEnvironmentField] = {
|
||||
environmentField_=(Seq(theField))
|
||||
}
|
||||
|
||||
def environmentField_=(theFields: Seq[CreateEnvironmentField]): Seq[CreateEnvironmentField] = {
|
||||
fields = fields ++ theFields
|
||||
environmentField
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.equipment.EffectTarget
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -16,13 +15,12 @@ import scala.concurrent.duration.{Duration, FiniteDuration}
|
|||
* between the server and client using `ProximityTerminalUseMessage` game packets.
|
||||
*/
|
||||
trait ProximityDefinition {
|
||||
this: ObjectDefinition =>
|
||||
|
||||
private var interval: FiniteDuration = Duration(0, "seconds")
|
||||
private var useRadius: Float = 0f //TODO belongs on a wider range of object definitions
|
||||
private val targetValidation: mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean] =
|
||||
new mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean]()
|
||||
|
||||
def UseRadius: Float
|
||||
|
||||
def Interval: FiniteDuration = interval
|
||||
|
||||
def Interval_=(amount: Int): FiniteDuration = {
|
||||
|
|
@ -34,13 +32,6 @@ trait ProximityDefinition {
|
|||
Interval
|
||||
}
|
||||
|
||||
def UseRadius: Float = useRadius
|
||||
|
||||
def UseRadius_=(radius: Float): Float = {
|
||||
useRadius = radius
|
||||
UseRadius
|
||||
}
|
||||
|
||||
def TargetValidation: mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean] = targetValidation
|
||||
|
||||
def Validations: Seq[PlanetSideGameObject => Boolean] = {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ 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.doors.Door
|
||||
import net.psforever.objects.serverobject.environment.EnvironmentAttribute
|
||||
import net.psforever.objects.serverobject.interior.{InteriorAware, Sidedness}
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
|
|
@ -966,7 +967,7 @@ object Zone {
|
|||
map.doorToLock
|
||||
.map { case (door, lock) => (guid(door), guid(lock)) }
|
||||
.collect { case (Some(door: Door), Some(lock: IFFLock))
|
||||
if door.Definition.geometryInteractionRadius.nonEmpty =>
|
||||
if door.Definition.environmentField.exists(f => f.attribute == EnvironmentAttribute.InteriorField) =>
|
||||
door.WhichSide = Sidedness.StrictlyBetweenSides
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
|
|
@ -1103,7 +1104,7 @@ object Zone {
|
|||
.map { case (door, lock) => (guid(door), guid(lock))}
|
||||
.collect {
|
||||
case (Some(door: Door), Some(lock: IFFLock))
|
||||
if door.Definition.geometryInteractionRadius.nonEmpty =>
|
||||
if door.Definition.environmentField.exists(f => f.attribute == EnvironmentAttribute.InteriorField) =>
|
||||
lock.WhichSide = Sidedness.OutsideOf
|
||||
}
|
||||
//medical terminals are always inside
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package net.psforever.objects.zones.blockmap
|
|||
import net.psforever.objects.ballistics.Projectile
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.serverobject.doors.{Door, InteriorDoorPassage}
|
||||
import net.psforever.objects.serverobject.environment.PieceOfEnvironment
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||
import net.psforever.objects.{Player, Vehicle}
|
||||
|
|
@ -200,14 +199,12 @@ class Sector(val longitude: Int, val latitude: Int, val span: Int)
|
|||
deployables.list.size < deployables.addTo(d).size
|
||||
case b: Building =>
|
||||
buildings.list.size < buildings.addTo(b).size
|
||||
case d: Door =>
|
||||
val doorAdded = amenities.list.size < amenities.addTo(d).size
|
||||
d.Definition.geometryInteractionRadius.collect {
|
||||
case _ if doorAdded => environment.addTo(InteriorDoorPassage(d))
|
||||
}
|
||||
doorAdded
|
||||
case a: Amenity =>
|
||||
amenities.list.size < amenities.addTo(a).size
|
||||
val added = amenities.list.size < amenities.addTo(a).size
|
||||
if (added) {
|
||||
a.Definition.environmentField.foreach(field => environment.addTo(field.create(a)))
|
||||
}
|
||||
added
|
||||
case e: PieceOfEnvironment =>
|
||||
environment.list.size < environment.addTo(e).size
|
||||
case p: Projectile =>
|
||||
|
|
|
|||
Loading…
Reference in a new issue