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:
Fate-JH 2024-01-30 18:49:06 -05:00
parent e6ec5b1ee4
commit c97732dfe9
7 changed files with 234 additions and 151 deletions

View file

@ -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

View file

@ -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)

View file

@ -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(

View file

@ -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 _ => ()
}
}
}

View file

@ -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)
}
}

View file

@ -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())
}
}
}

View file

@ -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
)
/**