mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
redid combat engineering explosive logic
This commit is contained in:
parent
fa9ba7e7da
commit
38f25f5bcc
|
|
@ -5,7 +5,6 @@ import akka.actor.{ActorContext, Props}
|
|||
import net.psforever.objects.ce.{Deployable, DeployedItem}
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.Vitality
|
||||
|
|
@ -39,7 +38,8 @@ class BoomerDeployable(cdef: ExplosiveDeployableDefinition)
|
|||
}
|
||||
}
|
||||
|
||||
class BoomerDeployableDefinition(private val objectId: Int) extends ExplosiveDeployableDefinition(objectId) {
|
||||
class BoomerDeployableDefinition(private val objectId: Int)
|
||||
extends ExplosiveDeployableDefinition(objectId) {
|
||||
override def Initialize(obj: Deployable, context: ActorContext): Unit = {
|
||||
obj.Actor =
|
||||
context.actorOf(Props(classOf[BoomerDeployableControl], obj), PlanetSideServerObject.UniqueActorName(obj))
|
||||
|
|
@ -119,6 +119,6 @@ class BoomerDeployableControl(mine: BoomerDeployable)
|
|||
* `false`, otherwise
|
||||
*/
|
||||
override def CanDetonate(obj: Vitality with FactionAffinity, damage: Int, data: DamageInteraction): Boolean = {
|
||||
!mine.Destroyed && (data.cause.isInstanceOf[TriggerUsedReason] || Damageable.CanJammer(obj, data))
|
||||
super.CanDetonate(obj, damage, data) || data.cause.isInstanceOf[TriggerUsedReason]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2018 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import akka.actor.{Actor, ActorContext, ActorRef, Props}
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.ce._
|
||||
import net.psforever.objects.definition.DeployableDefinition
|
||||
import net.psforever.objects.definition.converter.SmallDeployableConverter
|
||||
|
|
@ -11,8 +11,6 @@ import net.psforever.objects.serverobject.affinity.FactionAffinity
|
|||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.damage.{Damageable, DamageableEntity}
|
||||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||
import net.psforever.objects.sourcing.{DeployableSource, PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.etc.TrippedMineReason
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations.Output
|
||||
import net.psforever.objects.vital.{SimpleResolutions, Vitality}
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
|
|
@ -23,6 +21,7 @@ import net.psforever.services.Service
|
|||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
|
||||
import scala.annotation.unused
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class ExplosiveDeployable(cdef: ExplosiveDeployableDefinition)
|
||||
|
|
@ -36,7 +35,7 @@ object ExplosiveDeployable {
|
|||
final case class TriggeredBy(obj: PlanetSideServerObject)
|
||||
}
|
||||
|
||||
class ExplosiveDeployableDefinition(private val objectId: Int)
|
||||
abstract class ExplosiveDeployableDefinition(private val objectId: Int)
|
||||
extends DeployableDefinition(objectId) {
|
||||
Name = "explosive_deployable"
|
||||
DeployCategory = DeployableCategory.Mines
|
||||
|
|
@ -45,6 +44,8 @@ class ExplosiveDeployableDefinition(private val objectId: Int)
|
|||
|
||||
private var detonateOnJamming: Boolean = true
|
||||
|
||||
private var stability: Boolean = false
|
||||
|
||||
var triggerRadius: Float = 0f
|
||||
|
||||
def DetonateOnJamming: Boolean = detonateOnJamming
|
||||
|
|
@ -54,15 +55,11 @@ class ExplosiveDeployableDefinition(private val objectId: Int)
|
|||
DetonateOnJamming
|
||||
}
|
||||
|
||||
override def Initialize(obj: Deployable, context: ActorContext): Unit = {
|
||||
obj.Actor =
|
||||
context.actorOf(Props(classOf[MineDeployableControl], obj), PlanetSideServerObject.UniqueActorName(obj))
|
||||
}
|
||||
}
|
||||
def Stable: Boolean = stability
|
||||
|
||||
object ExplosiveDeployableDefinition {
|
||||
def apply(dtype: DeployedItem.Value): ExplosiveDeployableDefinition = {
|
||||
new ExplosiveDeployableDefinition(dtype.id)
|
||||
def Stable_=(stableState: Boolean): Boolean = {
|
||||
stability = stableState
|
||||
Stable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,19 +95,10 @@ abstract class ExplosiveDeployableControl(mine: ExplosiveDeployable)
|
|||
}
|
||||
}
|
||||
|
||||
def Interaction(obj: Vitality with FactionAffinity, damage: Int, data: DamageInteraction): Boolean = {
|
||||
!mine.Destroyed && (if (damage == 0 && data.cause.source.SympatheticExplosion) {
|
||||
Damageable.CanDamageOrJammer(obj, damage = 1, data)
|
||||
} else {
|
||||
Damageable.CanDamageOrJammer(obj, damage, data)
|
||||
})
|
||||
}
|
||||
|
||||
final def HandleDamage(target: ExplosiveDeployable, cause: DamageResult, damage: Int): Unit = {
|
||||
target.LogActivity(cause)
|
||||
if (CanDetonate(target, damage, cause.interaction)) {
|
||||
ExplosiveDeployableControl.explodes(target, cause)
|
||||
ExplosiveDeployableControl.DestructionAwareness(target, cause)
|
||||
ExplosiveDeployableControl.doExplosion(target, cause)
|
||||
} else if (target.Health == 0) {
|
||||
ExplosiveDeployableControl.DestructionAwareness(target, cause)
|
||||
} else {
|
||||
|
|
@ -118,6 +106,17 @@ abstract class ExplosiveDeployableControl(mine: ExplosiveDeployable)
|
|||
}
|
||||
}
|
||||
|
||||
def Interaction(obj: Vitality with FactionAffinity, damage: Int, data: DamageInteraction): Boolean = {
|
||||
val actualDamage: Int = if (!mine.Definition.Stable && data.cause.source.SympatheticExplosion) {
|
||||
math.max(damage, 1)
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
!mine.Destroyed &&
|
||||
Damageable.adversarialOrHackableChecks(obj, data) &&
|
||||
(CanDetonate(obj, actualDamage, data) || Damageable.CanDamage(obj, actualDamage, data))
|
||||
}
|
||||
|
||||
/**
|
||||
* A supplement for checking target susceptibility
|
||||
* to account for sympathetic explosives even if there is no damage.
|
||||
|
|
@ -130,21 +129,22 @@ abstract class ExplosiveDeployableControl(mine: ExplosiveDeployable)
|
|||
* @return `true`, if the target can be affected;
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def CanDetonate(obj: Vitality with FactionAffinity, damage: Int, data: DamageInteraction): Boolean = {
|
||||
!mine.Destroyed && (if (damage == 0 && data.cause.source.SympatheticExplosion) {
|
||||
Damageable.CanDamageOrJammer(mine, damage = 1, data)
|
||||
} else {
|
||||
Damageable.CanDamageOrJammer(mine, damage, data)
|
||||
})
|
||||
}
|
||||
|
||||
def explode(target: ExplosiveDeployable, cause: DamageResult): Unit = {
|
||||
ExplosiveDeployableControl.explodes(target, cause)
|
||||
ExplosiveDeployableControl.DestructionAwareness(target, cause)
|
||||
def CanDetonate(obj: Vitality with FactionAffinity, @unused damage: Int, data: DamageInteraction): Boolean = {
|
||||
val sourceDef = data.cause.source
|
||||
val mineDef = mine.Definition
|
||||
val explodeFromSympathy: Boolean = sourceDef.SympatheticExplosion && !mineDef.Stable
|
||||
val explodeFromJammer: Boolean = ExplosiveDeployableControl.CanJammer(mine, data)
|
||||
!mine.Destroyed && (explodeFromSympathy || explodeFromJammer)
|
||||
}
|
||||
}
|
||||
|
||||
object ExplosiveDeployableControl {
|
||||
def CanJammer(mine: ExplosiveDeployable, data: DamageInteraction): Boolean = {
|
||||
Damageable.adversarialOrHackableChecks(mine, data) &&
|
||||
data.cause.source.AdditionalEffect &&
|
||||
mine.Definition.DetonateOnJamming
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
|
|
@ -152,22 +152,23 @@ object ExplosiveDeployableControl {
|
|||
* @param damage na
|
||||
*/
|
||||
def DamageAwareness(target: ExplosiveDeployable, cause: DamageResult, damage: Int): Unit = {
|
||||
if (!target.Jammed && Damageable.CanJammer(target, cause.interaction)) {
|
||||
if ( {
|
||||
target.Jammed = cause.interaction.cause match {
|
||||
case o: ProjectileReason =>
|
||||
val radius = o.projectile.profile.DamageRadius
|
||||
Vector3.DistanceSquared(cause.interaction.hitPos, cause.interaction.target.Position) < radius * radius
|
||||
case _ =>
|
||||
true
|
||||
if (
|
||||
!target.Jammed &&
|
||||
CanJammer(target, cause.interaction) &&
|
||||
{
|
||||
target.Jammed = cause.interaction.cause match {
|
||||
case o: ProjectileReason =>
|
||||
val radius = o.projectile.profile.DamageRadius
|
||||
Vector3.DistanceSquared(cause.interaction.hitPos, cause.interaction.target.Position) < radius * radius
|
||||
case _ =>
|
||||
true
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (target.Definition.DetonateOnJamming) {
|
||||
explodes(target, cause)
|
||||
}
|
||||
) {
|
||||
if (target.Definition.DetonateOnJamming) {
|
||||
explodes(target, cause)
|
||||
}
|
||||
DestructionAwareness(target, cause)
|
||||
}
|
||||
DestructionAwareness(target, cause)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -190,6 +191,11 @@ object ExplosiveDeployableControl {
|
|||
)
|
||||
}
|
||||
|
||||
def doExplosion(target: ExplosiveDeployable, cause: DamageResult): Unit = {
|
||||
explodes(target, cause)
|
||||
DestructionAwareness(target, cause)
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
|
|
@ -272,112 +278,3 @@ object ExplosiveDeployableControl {
|
|||
) <= maxDistance
|
||||
}
|
||||
}
|
||||
|
||||
class MineDeployableControl(mine: ExplosiveDeployable)
|
||||
extends ExplosiveDeployableControl(mine) {
|
||||
|
||||
def receive: Receive =
|
||||
commonMineBehavior
|
||||
.orElse {
|
||||
case ExplosiveDeployable.TriggeredBy(obj) =>
|
||||
setTriggered(Some(obj), delay = 200)
|
||||
|
||||
case MineDeployableControl.Triggered() =>
|
||||
explodes(testForTriggeringTarget(
|
||||
mine,
|
||||
mine.Definition.innateDamage.map { _.DamageRadius }.getOrElse(mine.Definition.triggerRadius)
|
||||
))
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
override def finalizeDeployable(callback: ActorRef): Unit = {
|
||||
super.finalizeDeployable(callback)
|
||||
//initial triggering upon build
|
||||
setTriggered(testForTriggeringTarget(mine, mine.Definition.triggerRadius), delay = 1000)
|
||||
}
|
||||
|
||||
def testForTriggeringTarget(mine: ExplosiveDeployable, range: Float): Option[PlanetSideServerObject] = {
|
||||
val position = mine.Position
|
||||
val faction = mine.Faction
|
||||
val range2 = range * range
|
||||
val sector = mine.Zone.blockMap.sector(position, range)
|
||||
(sector.livePlayerList ++ sector.vehicleList)
|
||||
.find { thing => thing.Faction != faction && Vector3.DistanceSquared(thing.Position, position) < range2 }
|
||||
}
|
||||
|
||||
def setTriggered(instigator: Option[PlanetSideServerObject], delay: Long): Unit = {
|
||||
instigator
|
||||
.collect {
|
||||
case _ if isConstructed.contains(true) && setup.isCancelled =>
|
||||
//re-use the setup timer here
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
setup = context.system.scheduler.scheduleOnce(delay milliseconds, self, MineDeployableControl.Triggered())
|
||||
}
|
||||
}
|
||||
|
||||
def explodes(instigator: Option[PlanetSideServerObject]): Unit = {
|
||||
instigator
|
||||
.collect {
|
||||
case _ =>
|
||||
//explosion
|
||||
mine.Destroyed = true
|
||||
ExplosiveDeployableControl.DamageAwareness(
|
||||
mine,
|
||||
DamageInteraction(
|
||||
SourceEntry(mine),
|
||||
MineDeployableControl.trippedMineReason(mine),
|
||||
mine.Position
|
||||
).calculate()(mine),
|
||||
damage = 0
|
||||
)
|
||||
}
|
||||
.orElse {
|
||||
//reset
|
||||
setup = Default.Cancellable
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object MineDeployableControl {
|
||||
private case class Triggered()
|
||||
|
||||
def trippedMineReason(mine: ExplosiveDeployable): TrippedMineReason = {
|
||||
lazy val deployableSource = DeployableSource(mine)
|
||||
val zone = mine.Zone
|
||||
val ownerName = mine.OwnerName
|
||||
val blame = zone
|
||||
.Players
|
||||
.find(a => ownerName.contains(a.name))
|
||||
.collect { a =>
|
||||
val name = a.name
|
||||
assignBlameToFrom(name, zone.LivePlayers)
|
||||
.orElse(assignBlameToFrom(name, zone.Corpses))
|
||||
.getOrElse {
|
||||
val player = PlayerSource(name, mine.Faction, mine.Position) //might report minor inconsistencies, e.g., exo-suit type
|
||||
player.copy(unique = player.unique.copy(charId = a.id), progress = a.scorecard.CurrentLife)
|
||||
}
|
||||
}
|
||||
.getOrElse(deployableSource)
|
||||
TrippedMineReason(deployableSource, blame)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a player with a given name from this list of possible players.
|
||||
* If the player is seated, attach a shallow copy of the mounting information.
|
||||
* @param name player name
|
||||
* @param blameList possible players in which to find the player name
|
||||
* @return discovered player as a reference, or `None` if not found
|
||||
*/
|
||||
private def assignBlameToFrom(name: String, blameList: List[Player]): Option[SourceEntry] = {
|
||||
blameList
|
||||
.find(_.Name.equals(name))
|
||||
.map { player =>
|
||||
PlayerSource
|
||||
.mountableAndSeat(player)
|
||||
.map { case (mount, seat) => PlayerSource.inSeat(player, mount, seat) }
|
||||
.getOrElse { PlayerSource(player) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1019,9 +1019,9 @@ object GlobalDefinitions {
|
|||
*/
|
||||
val boomer: BoomerDeployableDefinition = BoomerDeployableDefinition(DeployedItem.boomer)
|
||||
|
||||
val he_mine: ExplosiveDeployableDefinition = ExplosiveDeployableDefinition(DeployedItem.he_mine)
|
||||
val he_mine: MineDeployableDefinition = MineDeployableDefinition(DeployedItem.he_mine)
|
||||
|
||||
val jammer_mine: ExplosiveDeployableDefinition = ExplosiveDeployableDefinition(DeployedItem.jammer_mine)
|
||||
val jammer_mine: MineDeployableDefinition = MineDeployableDefinition(DeployedItem.jammer_mine)
|
||||
|
||||
val spitfire_turret: TurretDeployableDefinition = TurretDeployableDefinition(DeployedItem.spitfire_turret)
|
||||
|
||||
|
|
|
|||
137
src/main/scala/net/psforever/objects/MineDeployableControl.scala
Normal file
137
src/main/scala/net/psforever/objects/MineDeployableControl.scala
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import akka.actor.{ActorContext, ActorRef, Props}
|
||||
import net.psforever.objects.ce.{Deployable, DeployedItem}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.sourcing.{DeployableSource, PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.vital.etc.TrippedMineReason
|
||||
import net.psforever.objects.vital.interaction.DamageInteraction
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class MineDeployableDefinition(private val objectId: Int)
|
||||
extends ExplosiveDeployableDefinition(objectId) {
|
||||
override def Initialize(obj: Deployable, context: ActorContext): Unit = {
|
||||
obj.Actor =
|
||||
context.actorOf(Props(classOf[MineDeployableControl], obj), PlanetSideServerObject.UniqueActorName(obj))
|
||||
}
|
||||
}
|
||||
|
||||
object MineDeployableDefinition {
|
||||
def apply(dtype: DeployedItem.Value): MineDeployableDefinition = {
|
||||
new MineDeployableDefinition(dtype.id)
|
||||
}
|
||||
}
|
||||
|
||||
class MineDeployableControl(mine: ExplosiveDeployable)
|
||||
extends ExplosiveDeployableControl(mine) {
|
||||
|
||||
def receive: Receive =
|
||||
commonMineBehavior
|
||||
.orElse {
|
||||
case ExplosiveDeployable.TriggeredBy(obj) =>
|
||||
setTriggered(Some(obj), delay = 200)
|
||||
|
||||
case MineDeployableControl.Triggered() =>
|
||||
explodes(testForTriggeringTarget(
|
||||
mine,
|
||||
mine.Definition.innateDamage.map { _.DamageRadius }.getOrElse(mine.Definition.triggerRadius)
|
||||
))
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
override def finalizeDeployable(callback: ActorRef): Unit = {
|
||||
super.finalizeDeployable(callback)
|
||||
//initial triggering upon build
|
||||
setTriggered(testForTriggeringTarget(mine, mine.Definition.triggerRadius), delay = 1000)
|
||||
}
|
||||
|
||||
def testForTriggeringTarget(mine: ExplosiveDeployable, range: Float): Option[PlanetSideServerObject] = {
|
||||
val position = mine.Position
|
||||
val faction = mine.Faction
|
||||
val range2 = range * range
|
||||
val sector = mine.Zone.blockMap.sector(position, range)
|
||||
(sector.livePlayerList ++ sector.vehicleList)
|
||||
.find { thing => thing.Faction != faction && Vector3.DistanceSquared(thing.Position, position) < range2 }
|
||||
}
|
||||
|
||||
def setTriggered(instigator: Option[PlanetSideServerObject], delay: Long): Unit = {
|
||||
instigator
|
||||
.collect {
|
||||
case _ if isConstructed.contains(true) && setup.isCancelled =>
|
||||
//re-use the setup timer here
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
setup = context.system.scheduler.scheduleOnce(delay milliseconds, self, MineDeployableControl.Triggered())
|
||||
}
|
||||
}
|
||||
|
||||
override def CanDetonate(obj: Vitality with FactionAffinity, damage: Int, data: DamageInteraction): Boolean = {
|
||||
super.CanDetonate(obj, damage, data) || data.cause.isInstanceOf[TrippedMineReason]
|
||||
}
|
||||
|
||||
def explodes(instigator: Option[PlanetSideServerObject]): Unit = {
|
||||
//reset
|
||||
setup = Default.Cancellable
|
||||
instigator
|
||||
.collect {
|
||||
case _ =>
|
||||
//explosion
|
||||
HandleDamage(
|
||||
mine,
|
||||
DamageInteraction(
|
||||
SourceEntry(mine),
|
||||
MineDeployableControl.trippedMineReason(mine),
|
||||
mine.Position
|
||||
).calculate()(mine),
|
||||
damage = 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object MineDeployableControl {
|
||||
private case class Triggered()
|
||||
|
||||
def trippedMineReason(mine: ExplosiveDeployable): TrippedMineReason = {
|
||||
lazy val deployableSource = DeployableSource(mine)
|
||||
val zone = mine.Zone
|
||||
val ownerName = mine.OwnerName
|
||||
val blame = zone
|
||||
.Players
|
||||
.find(a => ownerName.contains(a.name))
|
||||
.collect { a =>
|
||||
val name = a.name
|
||||
assignBlameToFrom(name, zone.LivePlayers)
|
||||
.orElse(assignBlameToFrom(name, zone.Corpses))
|
||||
.getOrElse {
|
||||
val player = PlayerSource(name, mine.Faction, mine.Position) //might report minor inconsistencies, e.g., exo-suit type
|
||||
player.copy(unique = player.unique.copy(charId = a.id), progress = a.scorecard.CurrentLife)
|
||||
}
|
||||
}
|
||||
.getOrElse(deployableSource)
|
||||
TrippedMineReason(deployableSource, blame)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a player with a given name from this list of possible players.
|
||||
* If the player is seated, attach a shallow copy of the mounting information.
|
||||
* @param name player name
|
||||
* @param blameList possible players in which to find the player name
|
||||
* @return discovered player as a reference, or `None` if not found
|
||||
*/
|
||||
private def assignBlameToFrom(name: String, blameList: List[Player]): Option[SourceEntry] = {
|
||||
blameList
|
||||
.find(_.Name.equals(name))
|
||||
.map { player =>
|
||||
PlayerSource
|
||||
.mountableAndSeat(player)
|
||||
.map { case (mount, seat) => PlayerSource.inSeat(player, mount, seat) }
|
||||
.getOrElse { PlayerSource(player) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ object GlobalDefinitionsDeployable {
|
|||
boomer.DeployTime = Duration.create(1000, "ms")
|
||||
boomer.deployAnimation = DeployAnimation.Standard
|
||||
boomer.interference = InterferenceRange(main = 0.2f)
|
||||
boomer.Stable = true
|
||||
boomer.innateDamage = new DamageWithPosition {
|
||||
CausesDamageType = DamageType.Splash
|
||||
SympatheticExplosion = true
|
||||
|
|
@ -58,7 +59,7 @@ object GlobalDefinitionsDeployable {
|
|||
|
||||
he_mine.Name = "he_mine"
|
||||
he_mine.Descriptor = "Mines"
|
||||
he_mine.MaxHealth = 50
|
||||
he_mine.MaxHealth = 25
|
||||
he_mine.Damageable = true
|
||||
he_mine.DamageableByFriendlyFire = false
|
||||
he_mine.Repairable = false
|
||||
|
|
@ -91,12 +92,12 @@ object GlobalDefinitionsDeployable {
|
|||
jammer_mine.interference = InterferenceRange(main = 7f, sharedGroupId = 1, shared = 7f, deployables = 0.1f)
|
||||
jammer_mine.DetonateOnJamming = false
|
||||
jammer_mine.triggerRadius = 3f
|
||||
jammer_mine.Stable = true
|
||||
jammer_mine.innateDamage = new DamageWithPosition {
|
||||
CausesDamageType = DamageType.Splash
|
||||
Damage0 = 0
|
||||
DamageRadius = 10f
|
||||
DamageAtEdge = 1.0f
|
||||
AdditionalEffect = true
|
||||
JammedEffectDuration += TargetValidation(
|
||||
EffectTarget.Category.Player,
|
||||
EffectTarget.Validation.Player
|
||||
|
|
|
|||
|
|
@ -94,12 +94,12 @@ object Damageable {
|
|||
* `false`, otherwise
|
||||
*/
|
||||
def CanJammer(obj: Vitality with FactionAffinity, data: DamageInteraction): Boolean = {
|
||||
data.cause.source.HasJammedEffectDuration &&
|
||||
(data.cause.source.HasJammedEffectDuration || data.cause.source.AdditionalEffect) &&
|
||||
obj.isInstanceOf[JammableUnit] &&
|
||||
adversarialOrHackableChecks(obj, data)
|
||||
}
|
||||
|
||||
private def adversarialOrHackableChecks(obj: Vitality with FactionAffinity, data: DamageInteraction): Boolean = {
|
||||
def adversarialOrHackableChecks(obj: Vitality with FactionAffinity, data: DamageInteraction): Boolean = {
|
||||
(data.adversarial match {
|
||||
case Some(adversarial) => adversarial.attacker.Faction != adversarial.defender.Faction
|
||||
case None => true
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ trait DamageProperties
|
|||
* also used to produce staged projectiles */
|
||||
private var damageProxy: List[Int] = Nil
|
||||
/** na;
|
||||
* currently used with jammer properties only */
|
||||
* currently used with jammer properties only;
|
||||
* used sepcifically to indicate jammering effect targets explosive deployables */
|
||||
private var additionalEffect: Boolean = false
|
||||
/** confers aggravated damage burn to its target */
|
||||
private var aggravatedDamage: Option[AggravatedDamage] = None
|
||||
|
|
|
|||
Loading…
Reference in a new issue