mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Mine Distance (#1276)
* changing to square distance during mine checks; repeating entity geometric distance check function * added separate trigger radius rules for players and vehicles
This commit is contained in:
parent
5e0584b83b
commit
f74da61fa5
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.objects
|
package net.psforever.objects
|
||||||
|
|
||||||
import net.psforever.objects.avatar.interaction.{WithEntrance, WithGantry, WithLava, WithWater}
|
import net.psforever.objects.avatar.interaction.{TriggerOnPlayerRule, WithEntrance, WithGantry, WithLava, WithWater}
|
||||||
import net.psforever.objects.avatar.{Avatar, LoadoutManager, SpecialCarry}
|
import net.psforever.objects.avatar.{Avatar, LoadoutManager, SpecialCarry}
|
||||||
import net.psforever.objects.ballistics.InteractWithRadiationClouds
|
import net.psforever.objects.ballistics.InteractWithRadiationClouds
|
||||||
import net.psforever.objects.ce.{Deployable, InteractWithMines, InteractWithTurrets}
|
import net.psforever.objects.ce.{Deployable, InteractWithMines, InteractWithTurrets}
|
||||||
|
|
@ -47,7 +47,7 @@ class Player(var avatar: Avatar)
|
||||||
new WithGantry(avatar.name),
|
new WithGantry(avatar.name),
|
||||||
new WithMovementTrigger()
|
new WithMovementTrigger()
|
||||||
)))
|
)))
|
||||||
interaction(new InteractWithMines(range = 10))
|
interaction(new InteractWithMines(range = 10, TriggerOnPlayerRule))
|
||||||
interaction(new InteractWithTurrets())
|
interaction(new InteractWithTurrets())
|
||||||
interaction(new InteractWithRadiationClouds(range = 10f, Some(this)))
|
interaction(new InteractWithRadiationClouds(range = 10f, Some(this)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.serverobject.interior.{InteriorAwareFromInteraction, Sidedness}
|
import net.psforever.objects.serverobject.interior.{InteriorAwareFromInteraction, Sidedness}
|
||||||
import net.psforever.objects.serverobject.structures.AmenityOwner
|
import net.psforever.objects.serverobject.structures.AmenityOwner
|
||||||
import net.psforever.objects.vehicles._
|
import net.psforever.objects.vehicles._
|
||||||
import net.psforever.objects.vehicles.interaction.{WithLava, WithWater}
|
import net.psforever.objects.vehicles.interaction.{TriggerOnVehicleRule, WithLava, WithWater}
|
||||||
import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
||||||
import net.psforever.objects.vital.Vitality
|
import net.psforever.objects.vital.Vitality
|
||||||
import net.psforever.objects.vital.resolution.DamageResistanceModel
|
import net.psforever.objects.vital.resolution.DamageResistanceModel
|
||||||
|
|
@ -101,7 +101,7 @@ class Vehicle(private val vehicleDef: VehicleDefinition)
|
||||||
new WithDeath(),
|
new WithDeath(),
|
||||||
new WithMovementTrigger()
|
new WithMovementTrigger()
|
||||||
)))
|
)))
|
||||||
interaction(new InteractWithMines(range = 20))
|
interaction(new InteractWithMines(range = 20, TriggerOnVehicleRule))
|
||||||
interaction(new InteractWithTurrets())
|
interaction(new InteractWithTurrets())
|
||||||
interaction(new InteractWithRadiationCloudsSeatedInVehicle(obj = this, range = 20))
|
interaction(new InteractWithRadiationCloudsSeatedInVehicle(obj = this, range = 20))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright (c) 2025 PSForever
|
||||||
|
package net.psforever.objects.avatar.interaction
|
||||||
|
|
||||||
|
import net.psforever.objects.ce.TriggerTest
|
||||||
|
import net.psforever.objects.ExplosiveDeployable
|
||||||
|
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||||
|
import net.psforever.objects.zones.Zone
|
||||||
|
|
||||||
|
case object TriggerOnPlayerRule
|
||||||
|
extends TriggerTest {
|
||||||
|
def test(g: VolumetricGeometry, obj: ExplosiveDeployable, radius: Float): Boolean = {
|
||||||
|
Zone.distanceCheck(g, obj, radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) 2021 PSForever
|
// Copyright (c) 2021 PSForever
|
||||||
package net.psforever.objects.ce
|
package net.psforever.objects.ce
|
||||||
|
|
||||||
|
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||||
import net.psforever.objects.zones.blockmap.SectorPopulation
|
import net.psforever.objects.zones.blockmap.SectorPopulation
|
||||||
import net.psforever.objects.zones.{InteractsWithZone, Zone, ZoneInteraction, ZoneInteractionType}
|
import net.psforever.objects.zones.{InteractsWithZone, ZoneInteraction, ZoneInteractionType}
|
||||||
import net.psforever.objects.{BoomerDeployable, ExplosiveDeployable}
|
import net.psforever.objects.{BoomerDeployable, ExplosiveDeployable}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@ case object MineInteraction extends ZoneInteractionType
|
||||||
* "Interact", here, is a graceful word for "trample upon" and the consequence should be an explosion
|
* "Interact", here, is a graceful word for "trample upon" and the consequence should be an explosion
|
||||||
* and maybe death.
|
* and maybe death.
|
||||||
*/
|
*/
|
||||||
class InteractWithMines(val range: Float)
|
class InteractWithMines(val range: Float, rule: TriggerTest)
|
||||||
extends ZoneInteraction {
|
extends ZoneInteraction {
|
||||||
/**
|
/**
|
||||||
* mines that, though detected, are skipped from being alerted;
|
* mines that, though detected, are skipped from being alerted;
|
||||||
|
|
@ -23,7 +24,7 @@ class InteractWithMines(val range: Float)
|
||||||
*/
|
*/
|
||||||
private var skipTargets: List[PlanetSideGUID] = List()
|
private var skipTargets: List[PlanetSideGUID] = List()
|
||||||
|
|
||||||
def Type = MineInteraction
|
def Type: MineInteraction.type = MineInteraction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trample upon active mines in our current detection sector and alert those mines.
|
* Trample upon active mines in our current detection sector and alert those mines.
|
||||||
|
|
@ -32,12 +33,12 @@ class InteractWithMines(val range: Float)
|
||||||
*/
|
*/
|
||||||
def interaction(sector: SectorPopulation, target: InteractsWithZone): Unit = {
|
def interaction(sector: SectorPopulation, target: InteractsWithZone): Unit = {
|
||||||
val faction = target.Faction
|
val faction = target.Faction
|
||||||
|
lazy val targetGeometry = target.Definition.Geometry(target)
|
||||||
val targets = sector
|
val targets = sector
|
||||||
.deployableList
|
.deployableList
|
||||||
.filter {
|
.filter {
|
||||||
case _: BoomerDeployable => false //boomers are specific types of ExplosiveDeployable but do not count here
|
case _: BoomerDeployable => false //boomers are a specific type of ExplosiveDeployable that do not count here
|
||||||
case ex: ExplosiveDeployable => ex.Faction != faction &&
|
case ex: ExplosiveDeployable => ex.Faction != faction && rule.test(targetGeometry, ex, ex.Definition.triggerRadius)
|
||||||
Zone.distanceCheck(target, ex, ex.Definition.triggerRadius)
|
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
val notSkipped = targets.filterNot { t => skipTargets.contains(t.GUID) }
|
val notSkipped = targets.filterNot { t => skipTargets.contains(t.GUID) }
|
||||||
|
|
@ -56,3 +57,19 @@ class InteractWithMines(val range: Float)
|
||||||
skipTargets = List()
|
skipTargets = List()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The testing rule used to determine if a target is within range
|
||||||
|
* to agitate the game world deployable extra-territorial munitions.
|
||||||
|
*/
|
||||||
|
trait TriggerTest {
|
||||||
|
/**
|
||||||
|
* Perform the test
|
||||||
|
* @param g the geometric representation of a game entity
|
||||||
|
* @param obj a game entity
|
||||||
|
* @param distance the maximum distance permissible between game entities
|
||||||
|
* @return `true`, if the two entities are near enough to each other;
|
||||||
|
* `false`, otherwise
|
||||||
|
*/
|
||||||
|
def test(g: VolumetricGeometry, obj: ExplosiveDeployable, distance: Float): Boolean
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright (c) 2025 PSForever
|
||||||
|
package net.psforever.objects.vehicles.interaction
|
||||||
|
|
||||||
|
import net.psforever.objects.ce.TriggerTest
|
||||||
|
import net.psforever.objects.ExplosiveDeployable
|
||||||
|
import net.psforever.objects.geometry.d3.VolumetricGeometry
|
||||||
|
import net.psforever.objects.zones.Zone
|
||||||
|
|
||||||
|
case object TriggerOnVehicleRule
|
||||||
|
extends TriggerTest {
|
||||||
|
def test(g: VolumetricGeometry, obj: ExplosiveDeployable, radius: Float): Boolean = {
|
||||||
|
Zone.distanceCheck(g, obj, radius * radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1901,6 +1901,24 @@ object Zone {
|
||||||
distanceCheck(obj1.Definition.Geometry(obj1), obj2.Definition.Geometry(obj2), maxDistance)
|
distanceCheck(obj1.Definition.Geometry(obj1), obj2.Definition.Geometry(obj2), maxDistance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Two game entities are considered "near" each other if they are within a certain distance of one another.
|
||||||
|
* A default function literal mainly used for `serverSideDamage`.
|
||||||
|
* Best used when one entity - `obj1` - is to be reused in tests against multiple other entities
|
||||||
|
* as it skips repeatedly calculating the volumetric geometry of the repeating entity.
|
||||||
|
* @see `ObjectDefinition.Geometry`
|
||||||
|
* @see `serverSideDamage`
|
||||||
|
* @param obj1 the geometric representation of a game entity
|
||||||
|
* @param obj2 a game entity
|
||||||
|
* @param maxDistance the square of the maximum distance permissible between game entities
|
||||||
|
* before they are no longer considered "near"
|
||||||
|
* @return `true`, if the two entities are near enough to each other;
|
||||||
|
* `false`, otherwise
|
||||||
|
*/
|
||||||
|
def distanceCheck(obj1: VolumetricGeometry, obj2: PlanetSideGameObject, maxDistance: Float): Boolean = {
|
||||||
|
distanceCheck(obj1, obj2.Definition.Geometry(obj2), maxDistance)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Two game entities are considered "near" each other if they are within a certain distance of one another.
|
* Two game entities are considered "near" each other if they are within a certain distance of one another.
|
||||||
* @param g1 the geometric representation of a game entity
|
* @param g1 the geometric representation of a game entity
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue