mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
reactivating turret deployable destruction; clarifying the validation and clearing conditions for different kinds of auto turrets; extending self-reporting auto turret behavior to other auto-turrets
This commit is contained in:
parent
e6ec5b1ee4
commit
c97732dfe9
|
|
@ -9081,9 +9081,9 @@ object GlobalDefinitions {
|
|||
),
|
||||
AutoChecks(
|
||||
validation = List(
|
||||
EffectTarget.Validation.PlayerDetectedBySpitfireTurret,
|
||||
EffectTarget.Validation.GroundVehicleDetectedByAutoTurret,
|
||||
EffectTarget.Validation.AircraftDetectedByAutoTurret
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidatePlayerTarget,
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidateGroundVehicleTarget,
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidateAircraftTarget
|
||||
)
|
||||
),
|
||||
retaliatoryDelay = 2000L, //8000L
|
||||
|
|
@ -9123,9 +9123,9 @@ object GlobalDefinitions {
|
|||
),
|
||||
AutoChecks(
|
||||
validation = List(
|
||||
EffectTarget.Validation.PlayerDetectedBySpitfireTurret,
|
||||
EffectTarget.Validation.GroundVehicleDetectedByAutoTurret,
|
||||
EffectTarget.Validation.AircraftDetectedByAutoTurret
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidatePlayerTarget,
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidateGroundVehicleTarget,
|
||||
EffectTarget.Validation.SmallRoboticsTurretValidateAircraftTarget
|
||||
)
|
||||
),
|
||||
cooldowns = AutoCooldowns(
|
||||
|
|
@ -9170,7 +9170,7 @@ object GlobalDefinitions {
|
|||
escape = 200f
|
||||
),
|
||||
AutoChecks(
|
||||
validation = List(EffectTarget.Validation.AircraftDetectedByAutoTurret)
|
||||
validation = List(EffectTarget.Validation.SmallRoboticsTurretValidateAircraftTarget)
|
||||
),
|
||||
retaliatoryDelay = 2000L, //8000L
|
||||
retaliationOverridesTarget = false,
|
||||
|
|
@ -10066,7 +10066,7 @@ object GlobalDefinitions {
|
|||
manned_turret.Name = "manned_turret"
|
||||
manned_turret.MaxHealth = 3600
|
||||
manned_turret.Damageable = true
|
||||
manned_turret.DamageDisablesAt = 0
|
||||
manned_turret.DamageDisablesAt = 1800
|
||||
manned_turret.Repairable = true
|
||||
manned_turret.autoRepair = AutoRepairStats(1.0909f, 10000, 1600, 0.05f)
|
||||
manned_turret.RepairIfDestroyed = true
|
||||
|
|
@ -10087,9 +10087,9 @@ object GlobalDefinitions {
|
|||
),
|
||||
AutoChecks(
|
||||
validation = List(
|
||||
EffectTarget.Validation.MaxDetectedByAutoTurret,
|
||||
EffectTarget.Validation.GroundVehicleDetectedByAutoTurret,
|
||||
EffectTarget.Validation.AircraftDetectedByAutoTurret
|
||||
EffectTarget.Validation.FacilityTurretValidateMaxTarget,
|
||||
EffectTarget.Validation.FacilityTurretValidateGroundVehicleTarget,
|
||||
EffectTarget.Validation.FacilityTurretValidateAircraftTarget
|
||||
)
|
||||
),
|
||||
retaliatoryDelay = 4000L, //8000L
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
|||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.turret.auto.{AutomatedTurret, AutomatedTurretBehavior}
|
||||
import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior}
|
||||
import net.psforever.objects.serverobject.turret.{MountableTurretControl, TurretDefinition, WeaponTurret}
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.damage.DamageCalculations
|
||||
|
|
@ -75,7 +75,8 @@ class TurretControl(turret: TurretDeployable)
|
|||
with DeployableBehavior
|
||||
with FactionAffinityBehavior.Check
|
||||
with MountableTurretControl
|
||||
with AutomatedTurretBehavior {
|
||||
with AutomatedTurretBehavior
|
||||
with AffectedByAutomaticTurretFire {
|
||||
def TurretObject: TurretDeployable = turret
|
||||
def DeployableObject: TurretDeployable = turret
|
||||
def MountableObject: TurretDeployable = turret
|
||||
|
|
@ -84,6 +85,7 @@ class TurretControl(turret: TurretDeployable)
|
|||
def DamageableObject: TurretDeployable = turret
|
||||
def RepairableObject: TurretDeployable = turret
|
||||
def AutomatedTurretObject: TurretDeployable = turret
|
||||
def AffectedObject: TurretDeployable = turret
|
||||
|
||||
override def postStop(): Unit = {
|
||||
super.postStop()
|
||||
|
|
@ -98,6 +100,7 @@ class TurretControl(turret: TurretDeployable)
|
|||
.orElse(checkBehavior)
|
||||
.orElse(mountBehavior)
|
||||
.orElse(automatedTurretBehavior)
|
||||
.orElse(takeAutomatedDamage)
|
||||
.orElse {
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -141,7 +144,7 @@ class TurretControl(turret: TurretDeployable)
|
|||
|
||||
override protected def DestructionAwareness(target: Target, cause: DamageResult): Unit = {
|
||||
AutomaticOperation = false
|
||||
//super.DestructionAwareness(target, cause)
|
||||
super.DestructionAwareness(target, cause)
|
||||
CancelJammeredSound(target)
|
||||
CancelJammeredStatus(target)
|
||||
Deployables.AnnounceDestroyDeployable(turret, None)
|
||||
|
|
|
|||
|
|
@ -189,9 +189,10 @@ object EffectTarget {
|
|||
false
|
||||
}
|
||||
|
||||
def PlayerDetectedBySpitfireTurret(target: PlanetSideGameObject): Boolean =
|
||||
!target.Destroyed && (target match {
|
||||
case p: Player =>
|
||||
def SmallRoboticsTurretValidatePlayerTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case p: Player
|
||||
if p.ExoSuit != ExoSuitType.MAX && p.VehicleSeated.isEmpty =>
|
||||
val now = System.currentTimeMillis()
|
||||
val pos = p.Position
|
||||
val faction = p.Faction
|
||||
|
|
@ -206,17 +207,51 @@ object EffectTarget {
|
|||
}
|
||||
.exists(_ < 2000L)
|
||||
lazy val silentRunActive = p.avatar.implants.flatten.find(a => a.definition.implantType == ImplantType.SilentRun).exists(_.active)
|
||||
lazy val movingFast = p.isMoving(test = 17d) || p.Jumping
|
||||
p.VehicleSeated.isEmpty &&
|
||||
(if (radarCloakedAms(sector, pos) || radarCloakedAegis(sector, pos)) false
|
||||
else if (radarCloakedSensor(sector, pos, faction)) tookDamage || usedEquipment
|
||||
else if (radarEnhancedInterlink(sector, pos, faction) || radarEnhancedSensor(sector, pos, faction)) true
|
||||
else tookDamage || usedEquipment || !silentRunActive && movingFast)
|
||||
lazy val cloakedByInfiltrationSuit = p.ExoSuit == ExoSuitType.Infiltration && p.Cloaked
|
||||
lazy val movingFast = p.isMoving(test = 17d)
|
||||
if (radarCloakedAms(sector, pos) || radarCloakedAegis(sector, pos)) false
|
||||
else if (radarCloakedSensor(sector, pos, faction)) tookDamage || usedEquipment
|
||||
else if (radarEnhancedInterlink(sector, pos, faction) || radarEnhancedSensor(sector, pos, faction)) true
|
||||
else tookDamage || usedEquipment || p.Jumping || (cloakedByInfiltrationSuit || !silentRunActive) && movingFast
|
||||
case _ =>
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
def PlayerUndetectedByAutoTurret(target: PlanetSideGameObject): Boolean =
|
||||
def SmallRoboticsTurretValidateMaxTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case p: Player
|
||||
if p.ExoSuit == ExoSuitType.MAX && p.VehicleSeated.isEmpty =>
|
||||
val now = System.currentTimeMillis()
|
||||
val pos = p.Position
|
||||
val faction = p.Faction
|
||||
val sector = p.Zone.blockMap.sector(p.Position, range = 51f)
|
||||
lazy val tookDamage = p.LastDamage.exists(dam => dam.adversarial.nonEmpty && now - dam.interaction.hitTime < 2000L)
|
||||
lazy val usedEquipment = p.Holsters().flatMap(_.Equipment)
|
||||
.collect { case t: Tool => now - t.LastDischarge }
|
||||
.exists(_ < 2000L)
|
||||
if (radarCloakedAms(sector, pos) || radarCloakedAegis(sector, pos)) false
|
||||
else if (radarCloakedSensor(sector, pos, faction)) tookDamage || usedEquipment
|
||||
else true
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def FacilityTurretValidateMaxTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case p: Player
|
||||
if p.ExoSuit == ExoSuitType.MAX && p.VehicleSeated.isEmpty =>
|
||||
val pos = p.Position
|
||||
val faction = p.Faction
|
||||
val sector = p.Zone.blockMap.sector(p.Position, range = 51f)
|
||||
!(radarCloakedAms(sector, pos) ||
|
||||
radarCloakedAegis(sector, pos) ||
|
||||
radarCloakedSensor(sector, pos, faction)) &&
|
||||
p.isMoving(test = 17d)
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def AutoTurretBlankPlayerTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case p: Player =>
|
||||
val pos = p.Position
|
||||
|
|
@ -226,38 +261,42 @@ object EffectTarget {
|
|||
false
|
||||
}
|
||||
|
||||
def MaxDetectedByAutoTurret(target: PlanetSideGameObject): Boolean =
|
||||
!target.Destroyed && (target match {
|
||||
case p: Player =>
|
||||
val now = System.currentTimeMillis()
|
||||
val pos = p.Position
|
||||
val faction = p.Faction
|
||||
val sector = p.Zone.blockMap.sector(p.Position, range = 51f)
|
||||
lazy val tookDamage = p.LastDamage.exists(dam => dam.adversarial.nonEmpty && now - dam.interaction.hitTime < 2000L)
|
||||
lazy val usedEquipment = p.Holsters().flatMap(_.Equipment)
|
||||
.collect { case t: Tool => now - t.LastDischarge }
|
||||
.exists(_ < 2000L)
|
||||
lazy val movingFast = p.isMoving(test = 17d)
|
||||
p.ExoSuit == ExoSuitType.MAX &&
|
||||
p.VehicleSeated.isEmpty &&
|
||||
(if (radarCloakedAms(sector, pos) || radarCloakedAegis(sector, pos)) false
|
||||
else if (radarCloakedSensor(sector, pos, faction)) tookDamage || usedEquipment
|
||||
else if (radarEnhancedInterlink(sector, pos, faction) || radarEnhancedSensor(sector, pos, faction)) true
|
||||
else tookDamage || usedEquipment || movingFast)
|
||||
case _ =>
|
||||
false
|
||||
})
|
||||
|
||||
def GroundVehicleDetectedByAutoTurret(target: PlanetSideGameObject): Boolean =
|
||||
!target.Destroyed && (target match {
|
||||
case v: Vehicle =>
|
||||
def SmallRoboticsTurretValidateGroundVehicleTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case v: Vehicle
|
||||
if v.MountedIn.isEmpty =>
|
||||
val now = System.currentTimeMillis()
|
||||
val vdef = v.Definition
|
||||
lazy val tookDamage = v.LastDamage.exists(dam => dam.adversarial.nonEmpty && now - dam.interaction.hitTime< 2000L)
|
||||
lazy val usedEquipment = v.Weapons.values.flatMap(_.Equipment)
|
||||
.collect { case t: Tool => now - t.LastDischarge }
|
||||
.exists(_ < 2000L)
|
||||
!GlobalDefinitions.isFlightVehicle(vdef) && v.MountedIn.isEmpty && (
|
||||
!GlobalDefinitions.isFlightVehicle(vdef) && (
|
||||
if (vdef == GlobalDefinitions.ams && v.DeploymentState == DriveState.Deployed) false
|
||||
else !v.Cloaked && ( tookDamage || usedEquipment))
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def SmallRoboticsTurretValidateAircraftTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case v: Vehicle if GlobalDefinitions.isFlightVehicle(v.Definition) =>
|
||||
!v.Cloaked
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def FacilityTurretValidateGroundVehicleTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case v: Vehicle
|
||||
if v.MountedIn.isEmpty =>
|
||||
val now = System.currentTimeMillis()
|
||||
val vdef = v.Definition
|
||||
lazy val tookDamage = v.LastDamage.exists(dam => dam.adversarial.nonEmpty && now - dam.interaction.hitTime< 2000L)
|
||||
lazy val usedEquipment = v.Weapons.values.flatMap(_.Equipment)
|
||||
.collect { case t: Tool => now - t.LastDischarge }
|
||||
.exists(_ < 2000L)
|
||||
!GlobalDefinitions.isFlightVehicle(vdef) && (
|
||||
if (vdef == GlobalDefinitions.ams && v.DeploymentState == DriveState.Deployed) false
|
||||
else if (
|
||||
v.Cloaked ||
|
||||
|
|
@ -268,23 +307,23 @@ object EffectTarget {
|
|||
else true)
|
||||
case _ =>
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
def VehicleUndetectedByAutoTurret(target: PlanetSideGameObject): Boolean =
|
||||
def FacilityTurretValidateAircraftTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case v: Vehicle if GlobalDefinitions.isFlightVehicle(v.Definition) =>
|
||||
v.Definition != GlobalDefinitions.mosquito || !v.Cloaked
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def AutoTurretBlankVehicleTarget(target: PlanetSideGameObject): Boolean =
|
||||
target match {
|
||||
case v: Vehicle =>
|
||||
(v.Definition == GlobalDefinitions.ams && v.DeploymentState == DriveState.Deployed) || v.MountedIn.nonEmpty || v.Cloaked
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
|
||||
def AircraftDetectedByAutoTurret(target: PlanetSideGameObject): Boolean =
|
||||
!target.Destroyed && (target match {
|
||||
case v: Vehicle =>
|
||||
GlobalDefinitions.isFlightVehicle(v.Definition) && !v.Cloaked
|
||||
case _ =>
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
private def radarEnhancedInterlink(
|
||||
|
|
|
|||
|
|
@ -5,42 +5,46 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
/**
|
||||
* The behaviours corresponding to an Amenity that is marked as being CaptureTerminalAware
|
||||
* @see CaptureTerminalAware
|
||||
*/
|
||||
trait CaptureTerminalAwareBehavior {
|
||||
def CaptureTerminalAwareObject : Amenity with CaptureTerminalAware
|
||||
def CaptureTerminalAwareObject: Amenity with CaptureTerminalAware
|
||||
|
||||
val captureTerminalAwareBehaviour: Receive = {
|
||||
case CaptureTerminalAwareBehavior.TerminalStatusChanged(terminal, isResecured) =>
|
||||
isResecured match {
|
||||
case true => ; // CC is resecured
|
||||
case false => // CC is hacked
|
||||
// Remove seated occupants for mountables
|
||||
CaptureTerminalAwareObject match {
|
||||
case mountable: Mountable =>
|
||||
case CaptureTerminalAwareBehavior.TerminalStatusChanged(terminal, true) =>
|
||||
captureTerminalIsResecured(terminal)
|
||||
|
||||
val guid = mountable.GUID
|
||||
val zone = mountable.Zone
|
||||
val zoneId = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
case CaptureTerminalAwareBehavior.TerminalStatusChanged(terminal, _) =>
|
||||
captureTerminalIsHacked(terminal)
|
||||
}
|
||||
|
||||
mountable.Seats.values.zipWithIndex.foreach {
|
||||
case (seat, seat_num) =>
|
||||
seat.occupant match {
|
||||
case Some(player) =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
if (player.HasGUID) {
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, seat_num, true, guid))
|
||||
}
|
||||
case None => ;
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
protected def captureTerminalIsResecured(@unused terminal: CaptureTerminal): Unit = { /* intentionally blank */ }
|
||||
|
||||
protected def captureTerminalIsHacked(@unused terminal: CaptureTerminal): Unit = {
|
||||
// Remove seated occupants for mountables
|
||||
CaptureTerminalAwareObject match {
|
||||
case mountable: Mountable =>
|
||||
val guid = mountable.GUID
|
||||
val zone = mountable.Zone
|
||||
val zoneId = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
mountable.Seats.values.zipWithIndex.foreach {
|
||||
case (seat, seat_num) =>
|
||||
seat.occupant.collect {
|
||||
case player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
if (player.HasGUID) {
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, seat_num, unk2=true, guid))
|
||||
}
|
||||
}
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import net.psforever.objects.serverobject.hackable.GenericHackables
|
|||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.repair.AmenityAutoRepair
|
||||
import net.psforever.objects.serverobject.structures.PoweredAmenityControl
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalAwareBehavior
|
||||
import net.psforever.objects.serverobject.turret.auto.{AutomatedTurret, AutomatedTurretBehavior}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAwareBehavior}
|
||||
import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior}
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.packet.game.ChangeFireModeMessage
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.BailType
|
||||
import net.psforever.types.{BailType, PlanetSideEmpire}
|
||||
|
||||
/**
|
||||
* A control agency that handles messages being dispatched to a specific `FacilityTurret`.
|
||||
|
|
@ -27,6 +27,7 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
with AmenityAutoRepair
|
||||
with MountableTurretControl
|
||||
with AutomatedTurretBehavior
|
||||
with AffectedByAutomaticTurretFire
|
||||
with CaptureTerminalAwareBehavior {
|
||||
def TurretObject: FacilityTurret = turret
|
||||
def FactionObject: FacilityTurret = turret
|
||||
|
|
@ -37,6 +38,7 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
def AutoRepairObject: FacilityTurret = turret
|
||||
def AutomatedTurretObject: FacilityTurret = turret
|
||||
def CaptureTerminalAwareObject: FacilityTurret = turret
|
||||
def AffectedObject: FacilityTurret = turret
|
||||
|
||||
private var testToResetToDefaultFireMode: Boolean = false
|
||||
|
||||
|
|
@ -70,6 +72,7 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
|
||||
override def commonBehavior: Receive = super.commonBehavior
|
||||
.orElse(automatedTurretBehavior)
|
||||
.orElse(takeAutomatedDamage)
|
||||
.orElse(captureTerminalAwareBehaviour)
|
||||
|
||||
override def poweredStateLogic: Receive =
|
||||
|
|
@ -247,4 +250,22 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
super.CancelJammeredStatus(target)
|
||||
startsJammed && AutomaticOperation_=(AutomaticOperationFunctionalityChecks)
|
||||
}
|
||||
|
||||
override protected def captureTerminalIsResecured(terminal: CaptureTerminal): Unit = {
|
||||
AutomaticOperation = if (terminal.Owner.Faction == PlanetSideEmpire.NEUTRAL) {
|
||||
false
|
||||
} else if (AutomaticOperation || AutomaticOperationFunctionalityChecks) {
|
||||
AutomaticOperation = false
|
||||
CurrentTargetLastShotReported = System.currentTimeMillis() + 5000L
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
super.captureTerminalIsResecured(terminal)
|
||||
}
|
||||
|
||||
override protected def captureTerminalIsHacked(terminal: CaptureTerminal): Unit = {
|
||||
AutomaticOperation = false
|
||||
super.captureTerminalIsHacked(terminal)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,36 +29,38 @@ trait AffectedByAutomaticTurretFire extends Damageable {
|
|||
|
||||
protected def performAutomatedDamage(turret: AutomatedTurret): Unit = {
|
||||
val target = AffectedObject
|
||||
val tool = turret.Weapons.values.head.Equipment.collect { case t: Tool => t }.get
|
||||
val projectileInfo = tool.Projectile
|
||||
val targetPos = target.Position
|
||||
val turretPos = turret.Position
|
||||
val correctedTargetPosition = targetPos + Vector3.z(value = 1f)
|
||||
val angle = Vector3.Unit(targetPos - turretPos)
|
||||
turret.Actor ! SelfReportedConfirmShot(target)
|
||||
val projectile = new Projectile(
|
||||
projectileInfo,
|
||||
tool.Definition,
|
||||
tool.FireMode,
|
||||
None,
|
||||
turret.TurretOwner,
|
||||
turret.Definition.ObjectId,
|
||||
turretPos + Vector3.z(value = 1f),
|
||||
angle,
|
||||
Some(angle * projectileInfo.FinalVelocity)
|
||||
)
|
||||
val modProjectile = ProjectileQuality.modifiers(
|
||||
projectile,
|
||||
DamageResolution.Hit,
|
||||
target,
|
||||
correctedTargetPosition,
|
||||
None
|
||||
)
|
||||
val resolvedProjectile = DamageInteraction(
|
||||
SourceEntry(target),
|
||||
ProjectileReason(DamageResolution.Hit, modProjectile, target.DamageModel),
|
||||
correctedTargetPosition
|
||||
)
|
||||
PerformDamage(target, resolvedProjectile.calculate())
|
||||
if (!target.isMoving(test = 1f)) {
|
||||
val tool = turret.Weapons.values.head.Equipment.collect { case t: Tool => t }.get
|
||||
val projectileInfo = tool.Projectile
|
||||
val targetPos = target.Position
|
||||
val turretPos = turret.Position
|
||||
val correctedTargetPosition = targetPos + Vector3.z(value = 1f)
|
||||
val angle = Vector3.Unit(targetPos - turretPos)
|
||||
turret.Actor ! SelfReportedConfirmShot(target)
|
||||
val projectile = new Projectile(
|
||||
projectileInfo,
|
||||
tool.Definition,
|
||||
tool.FireMode,
|
||||
None,
|
||||
turret.TurretOwner,
|
||||
turret.Definition.ObjectId,
|
||||
turretPos + Vector3.z(value = 1f),
|
||||
angle,
|
||||
Some(angle * projectileInfo.FinalVelocity)
|
||||
)
|
||||
val modProjectile = ProjectileQuality.modifiers(
|
||||
projectile,
|
||||
DamageResolution.Hit,
|
||||
target,
|
||||
correctedTargetPosition,
|
||||
None
|
||||
)
|
||||
val resolvedProjectile = DamageInteraction(
|
||||
SourceEntry(target),
|
||||
ProjectileReason(DamageResolution.Hit, modProjectile, target.DamageModel),
|
||||
correctedTargetPosition
|
||||
)
|
||||
PerformDamage(target, resolvedProjectile.calculate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,13 +306,16 @@ trait AutomatedTurretBehavior {
|
|||
val weaponGuid = AutomatedTurretObject.Weapons.values.head.Equipment.get.GUID
|
||||
val radius = autoStats.get.ranges.trigger
|
||||
val validation = autoStats.get.checks.validation
|
||||
val disqualifiers = autoStats.get.checks.blanking
|
||||
val faction = AutomatedTurretObject.Faction
|
||||
val selectedTargets = AutomatedTurretObject
|
||||
.Targets
|
||||
.collect { case target
|
||||
if target.Faction != faction &&
|
||||
if !target.Destroyed &&
|
||||
target.Faction != faction &&
|
||||
AutomatedTurretBehavior.shapedDistanceCheckAgainstValue(autoStats, target.Position, turretPosition, radius, result = -1) &&
|
||||
validation.exists(func => func(target)) =>
|
||||
validation.exists(func => func(target)) &&
|
||||
disqualifiers.takeWhile(func => func(target)).isEmpty =>
|
||||
target
|
||||
}
|
||||
val (previousTargets, newTargets) = selectedTargets.partition(target => previouslyTestedTargets.contains(SourceEntry(target).unique))
|
||||
|
|
@ -399,7 +402,7 @@ trait AutomatedTurretBehavior {
|
|||
AutomatedTurretDispatch.Generic.startShooting(target, target.Name, weaponGuid)
|
||||
AutomatedTurretDispatch.Generic.stopShooting(target, target.Name, weaponGuid)
|
||||
Some((target, target))
|
||||
case target: Vehicle =>
|
||||
case target: Mountable =>
|
||||
target.Seats.values
|
||||
.flatMap(_.occupants)
|
||||
.collectFirst { passenger =>
|
||||
|
|
@ -599,27 +602,7 @@ trait AutomatedTurretBehavior {
|
|||
selfReportingCleanUp()
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup for the variables involved in self-reporting.
|
||||
* Set them to zero.
|
||||
*/
|
||||
protected def selfReportingCleanUp(): Unit = {
|
||||
shotsFired = 0
|
||||
targetsDestroyed = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* The self-reporting mode for automatic turrets produces weapon fire data that should be sent to the database.
|
||||
* The targets destroyed from self-reported fire are also logged to the database.
|
||||
*/
|
||||
protected def selfReportingDatabaseUpdate(): Unit = {
|
||||
AutomatedTurretObject.TurretOwner match {
|
||||
case p: PlayerSource =>
|
||||
val weaponId = AutomatedTurretObject.Weapons.values.head.Equipment.map(_.Definition.ObjectId).getOrElse(0)
|
||||
ToDatabase.reportToolDischarge(p.CharId, EquipmentStat(weaponId, shotsFired, shotsFired, targetsDestroyed, 0))
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
/* Retaliation behavior */
|
||||
|
||||
/**
|
||||
* Retaliation is when a turret returns fire on a potential target that had just previously dealt damage to it.
|
||||
|
|
@ -656,18 +639,27 @@ trait AutomatedTurretBehavior {
|
|||
case existingTarget
|
||||
if autoStats.exists { auto =>
|
||||
auto.retaliationOverridesTarget &&
|
||||
currentTargetSwitchTime + auto.retaliatoryDelay > System.currentTimeMillis()
|
||||
currentTargetSwitchTime + auto.retaliatoryDelay > System.currentTimeMillis() &&
|
||||
auto.checks.blanking.takeWhile(func => func(target)).isEmpty
|
||||
} =>
|
||||
//conditions necessary for overriding the current target
|
||||
cancelSelfReportedAutoFire()
|
||||
noLongerEngageDetectedTarget(existingTarget)
|
||||
engageNewDetectedTarget(target)
|
||||
target
|
||||
|
||||
case existingTarget =>
|
||||
//stay with the current target
|
||||
existingTarget
|
||||
}
|
||||
.orElse {
|
||||
engageNewDetectedTarget(target)
|
||||
Some(target)
|
||||
//no current target
|
||||
if (autoStats.exists(_.checks.blanking.takeWhile(func => func(target)).isEmpty)) {
|
||||
engageNewDetectedTarget(target)
|
||||
Some(target)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -769,6 +761,28 @@ trait AutomatedTurretBehavior {
|
|||
selfReportedRefire = Default.Cancellable
|
||||
true
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup for the variables involved in self-reporting.
|
||||
* Set them to zero.
|
||||
*/
|
||||
protected def selfReportingCleanUp(): Unit = {
|
||||
shotsFired = 0
|
||||
targetsDestroyed = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* The self-reporting mode for automatic turrets produces weapon fire data that should be sent to the database.
|
||||
* The targets destroyed from self-reported fire are also logged to the database.
|
||||
*/
|
||||
protected def selfReportingDatabaseUpdate(): Unit = {
|
||||
AutomatedTurretObject.TurretOwner match {
|
||||
case p: PlayerSource =>
|
||||
val weaponId = AutomatedTurretObject.Weapons.values.head.Equipment.map(_.Definition.ObjectId).getOrElse(0)
|
||||
ToDatabase.reportToolDischarge(p.CharId, EquipmentStat(weaponId, shotsFired, shotsFired, targetsDestroyed, 0))
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object AutomatedTurretBehavior {
|
||||
|
|
@ -784,8 +798,8 @@ object AutomatedTurretBehavior {
|
|||
private case object PeriodicCheck
|
||||
|
||||
final val commonBlanking: List[PlanetSideGameObject => Boolean] = List(
|
||||
EffectTarget.Validation.PlayerUndetectedByAutoTurret,
|
||||
EffectTarget.Validation.VehicleUndetectedByAutoTurret
|
||||
EffectTarget.Validation.AutoTurretBlankPlayerTarget,
|
||||
EffectTarget.Validation.AutoTurretBlankVehicleTarget
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue