diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index c937e7c9..e00ecab5 100644 --- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -2686,6 +2686,14 @@ object GlobalDefinitions { jammer_cartridge_projectile.ProjectileDamageType = DamageType.Splash jammer_cartridge_projectile.InitialVelocity = 30 jammer_cartridge_projectile.Lifespan = 15f + jammer_cartridge_projectile.AdditionalEffect = true + jammer_cartridge_projectile.JammerProjectile = true + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Player, EffectTarget.Validation.Player) -> (1 seconds) + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.AMS) -> (5 seconds) + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.MotionSensor) -> (30 seconds) + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.Spitfire) -> (30 seconds) + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Turret, EffectTarget.Validation.Turret) -> (30 seconds) + jammer_cartridge_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.VehicleNotAMS) -> (10 seconds) ProjectileDefinition.CalculateDerivedFields(jammer_cartridge_projectile) jammer_cartridge_projectile_b.Name = "jammer_cartridge_projectile_b" @@ -2697,6 +2705,14 @@ object GlobalDefinitions { jammer_cartridge_projectile_b.ProjectileDamageType = DamageType.Splash jammer_cartridge_projectile_b.InitialVelocity = 30 jammer_cartridge_projectile_b.Lifespan = 2f + jammer_cartridge_projectile_b.AdditionalEffect = true + jammer_cartridge_projectile_b.JammerProjectile = true + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Player, EffectTarget.Validation.Player) -> (1 seconds) + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.AMS) -> (5 seconds) + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.MotionSensor) -> (30 seconds) + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.Spitfire) -> (30 seconds) + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Turret, EffectTarget.Validation.Turret) -> (30 seconds) + jammer_cartridge_projectile_b.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.VehicleNotAMS) -> (10 seconds) ProjectileDefinition.CalculateDerivedFields(jammer_cartridge_projectile_b) jammer_grenade_projectile.Name = "jammer_grenade_projectile" @@ -2707,6 +2723,14 @@ object GlobalDefinitions { jammer_grenade_projectile.ProjectileDamageType = DamageType.Splash jammer_grenade_projectile.InitialVelocity = 30 jammer_grenade_projectile.Lifespan = 15f + jammer_grenade_projectile.AdditionalEffect = true + jammer_grenade_projectile.JammerProjectile = true + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Player, EffectTarget.Validation.Player) -> (1 seconds) + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.AMS) -> (5 seconds) + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.MotionSensor) -> (30 seconds) + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.Spitfire) -> (30 seconds) + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Turret, EffectTarget.Validation.Turret) -> (30 seconds) + jammer_grenade_projectile.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.VehicleNotAMS) -> (10 seconds) ProjectileDefinition.CalculateDerivedFields(jammer_grenade_projectile) jammer_grenade_projectile_enh.Name = "jammer_grenade_projectile_enh" @@ -2718,6 +2742,13 @@ object GlobalDefinitions { jammer_grenade_projectile_enh.ProjectileDamageType = DamageType.Splash jammer_grenade_projectile_enh.InitialVelocity = 30 jammer_grenade_projectile_enh.Lifespan = 3f + jammer_grenade_projectile_enh.AdditionalEffect = true + jammer_grenade_projectile_enh.JammerProjectile = true + jammer_grenade_projectile_enh.JammedEffectDuration += TargetValidation(EffectTarget.Category.Player, EffectTarget.Validation.Player) -> (1 seconds) + jammer_grenade_projectile_enh.JammedEffectDuration += TargetValidation(EffectTarget.Category.Vehicle, EffectTarget.Validation.AMS) -> (5 seconds) + jammer_grenade_projectile_enh.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.MotionSensor) -> (30 seconds) + jammer_grenade_projectile_enh.JammedEffectDuration += TargetValidation(EffectTarget.Category.Deployable, EffectTarget.Validation.Spitfire) -> (30 seconds) + jammer_grenade_projectile_enh.JammedEffectDuration += TargetValidation(EffectTarget.Category.Turret, EffectTarget.Validation.Turret) -> (30 seconds) ProjectileDefinition.CalculateDerivedFields(jammer_grenade_projectile_enh) katana_projectile.Name = "katana_projectile" @@ -6096,62 +6127,62 @@ object GlobalDefinitions { teleportpad_terminal.Name = "teleportpad_terminal" teleportpad_terminal.Tab += 0 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.routerTerminal) - adv_med_terminal.Name = "adv_med_terminal" - adv_med_terminal.Interval = 500 - adv_med_terminal.HealAmount = 8 - adv_med_terminal.ArmorAmount = 15 - adv_med_terminal.UseRadius = 0.75f - adv_med_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical - - crystals_health_a.Name = "crystals_health_a" - crystals_health_a.Interval = 500 - crystals_health_a.HealAmount = 4 - crystals_health_a.UseRadius = 5 - crystals_health_a.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.HealthCrystal - - crystals_health_b.Name = "crystals_health_b" - crystals_health_b.Interval = 500 - crystals_health_b.HealAmount = 4 - crystals_health_b.UseRadius = 1.3f - crystals_health_b.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.HealthCrystal - medical_terminal.Name = "medical_terminal" medical_terminal.Interval = 500 medical_terminal.HealAmount = 5 medical_terminal.ArmorAmount = 10 medical_terminal.UseRadius = 0.75f - medical_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical + medical_terminal.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.Medical + + adv_med_terminal.Name = "adv_med_terminal" + adv_med_terminal.Interval = 500 + adv_med_terminal.HealAmount = 8 + adv_med_terminal.ArmorAmount = 15 + adv_med_terminal.UseRadius = 0.75f + adv_med_terminal.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.Medical + + crystals_health_a.Name = "crystals_health_a" + crystals_health_a.Interval = 500 + crystals_health_a.HealAmount = 4 + crystals_health_a.UseRadius = 5 + crystals_health_a.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.HealthCrystal + + crystals_health_b.Name = "crystals_health_b" + crystals_health_b.Interval = 500 + crystals_health_b.HealAmount = 4 + crystals_health_b.UseRadius = 1.3f + crystals_health_b.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.HealthCrystal portable_med_terminal.Name = "portable_med_terminal" portable_med_terminal.Interval = 500 portable_med_terminal.HealAmount = 5 portable_med_terminal.ArmorAmount = 10 portable_med_terminal.UseRadius = 3 - portable_med_terminal.TargetValidation += ProximityTarget.Player -> ProximityTerminalControl.Validation.Medical + portable_med_terminal.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.Medical pad_landing_frame.Name = "pad_landing_frame" pad_landing_frame.Interval = 1000 pad_landing_frame.HealAmount = 60 pad_landing_frame.UseRadius = 20 - pad_landing_frame.TargetValidation += ProximityTarget.Aircraft -> ProximityTerminalControl.Validation.PadLanding + pad_landing_frame.TargetValidation += EffectTarget.Category.Aircraft -> EffectTarget.Validation.PadLanding pad_landing_tower_frame.Name = "pad_landing_tower_frame" pad_landing_tower_frame.Interval = 1000 pad_landing_tower_frame.HealAmount = 60 pad_landing_tower_frame.UseRadius = 20 - pad_landing_tower_frame.TargetValidation += ProximityTarget.Aircraft -> ProximityTerminalControl.Validation.PadLanding + pad_landing_tower_frame.TargetValidation += EffectTarget.Category.Aircraft -> EffectTarget.Validation.PadLanding repair_silo.Name = "repair_silo" repair_silo.Interval = 1000 repair_silo.HealAmount = 60 repair_silo.UseRadius = 20 - repair_silo.TargetValidation += ProximityTarget.Vehicle -> ProximityTerminalControl.Validation.RepairSilo + repair_silo.TargetValidation += EffectTarget.Category.Vehicle -> EffectTarget.Validation.RepairSilo lodestar_repair_terminal.Name = "lodestar_repair_terminal" lodestar_repair_terminal.Interval = 1000 lodestar_repair_terminal.HealAmount = 60 lodestar_repair_terminal.UseRadius = 20 - lodestar_repair_terminal.TargetValidation += ProximityTarget.Vehicle -> ProximityTerminalControl.Validation.RepairSilo + lodestar_repair_terminal.TargetValidation += EffectTarget.Category.Vehicle -> EffectTarget.Validation.RepairSilo multivehicle_rearm_terminal.Name = "multivehicle_rearm_terminal" multivehicle_rearm_terminal.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition) diff --git a/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala index e1069612..01e6494c 100644 --- a/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/ProjectileDefinition.scala @@ -2,8 +2,12 @@ package net.psforever.objects.definition import net.psforever.objects.ballistics.Projectiles +import net.psforever.objects.serverobject.terminals.TargetValidation import net.psforever.objects.vital.{DamageType, StandardDamageProfile} +import scala.collection.mutable +import scala.concurrent.duration.Duration + /** * The definition that outlines the damage-dealing characteristics of any projectile. * `Tool` objects emit `ProjectileDefinition` objects and that is later wrapped into a `Projectile` object. @@ -26,6 +30,9 @@ class ProjectileDefinition(objectId : Int) extends ObjectDefinition(objectId) private var existsOnRemoteClients : Boolean = false //`true` spawns a server-managed object private var remoteClientData : (Int, Int) = (0, 0) //artificial values; for ObjectCreateMessage packet (oicw_little_buddy is undefined) private var autoLock : Boolean = false + private var additionalEffect : Boolean = false + private var jammerProjectile : Boolean = false + private val jammedEffectDuration : mutable.ListBuffer[(TargetValidation, Duration)] = new mutable.ListBuffer() //derived calculations private var distanceMax : Float = 0f private var distanceFromAcceleration : Float = 0f @@ -133,6 +140,24 @@ class ProjectileDefinition(objectId : Int) extends ObjectDefinition(objectId) AutoLock } + def AdditionalEffect : Boolean = additionalEffect + + def AdditionalEffect_=(effect : Boolean) : Boolean = { + additionalEffect = effect + AdditionalEffect + } + + def JammerProjectile : Boolean = jammerProjectile + + def JammerProjectile_=(effect : Boolean) : Boolean = { + jammerProjectile = effect + JammerProjectile + } + + def HasJammedEffectDuration : Boolean = jammedEffectDuration.isEmpty + + def JammedEffectDuration : mutable.ListBuffer[(TargetValidation, Duration)] = jammedEffectDuration + def DistanceMax : Float = distanceMax //accessor only def DistanceFromAcceleration : Float = distanceFromAcceleration //accessor only diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/EffectTarget.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/EffectTarget.scala new file mode 100644 index 00000000..38e790df --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/EffectTarget.scala @@ -0,0 +1,103 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects._ +import net.psforever.objects.ce.DeployableCategory +import net.psforever.objects.serverobject.turret.FacilityTurret + +final case class TargetValidation(category : EffectTarget.Category.Value, test : EffectTarget.Validation.Value) + +object EffectTarget { + /** + * A classification of the target of interactions. + * Arbitrary, but useful. + */ + object Category extends Enumeration { + val + Aircraft, + Deployable, + Equipment, + Player, + Turret, + Vehicle + = Value + } + + object Validation { + type Value = PlanetSideGameObject => Boolean + + def Invalid(target : PlanetSideGameObject) : Boolean = false + + def Medical(target : PlanetSideGameObject) : Boolean = target match { + case p : Player => + p.Health > 0 && (p.Health < p.MaxHealth || p.Armor < p.MaxArmor) + case _ => + false + } + + def HealthCrystal(target : PlanetSideGameObject) : Boolean = target match { + case p : Player => + p.Health > 0 && p.Health < p.MaxHealth + case _ => + false + } + + def RepairSilo(target : PlanetSideGameObject) : Boolean = target match { + case v : Vehicle => + !GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth + case _ => + false + } + + def PadLanding(target : PlanetSideGameObject) : Boolean = target match { + case v : Vehicle => + GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth + case _ => + false + } + + def Player(target : PlanetSideGameObject) : Boolean = target match { + case p : Player => + p.isAlive + case _ => + false + } + + def MotionSensor(target : PlanetSideGameObject) : Boolean = target match { + case s : SensorDeployable => + s.Health > 0 + case _ => + false + } + + def Spitfire(target : PlanetSideGameObject) : Boolean = target match { + case t : TurretDeployable => + t.Definition.DeployCategory == DeployableCategory.SmallTurrets && t.Health > 0 + case _ => + false + } + + def Turret(target : PlanetSideGameObject) : Boolean = target match { + case t : TurretDeployable => + t.Definition.DeployCategory == DeployableCategory.FieldTurrets && t.Health > 0 + case t : FacilityTurret => + t.Health > 0 + case _ => + false + } + + def AMS(target : PlanetSideGameObject) : Boolean = target match { + case v : Vehicle => + v.Health > 0 && v.Definition == GlobalDefinitions.ams + case _ => + false + } + + def VehicleNotAMS(target : PlanetSideGameObject) : Boolean = target match { + case v : Vehicle => + v.Health > 0 && v.Definition != GlobalDefinitions.ams + case _ => + false + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala index 575d6e55..4278cec0 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityDefinition.scala @@ -17,7 +17,7 @@ trait ProximityDefinition { this : ObjectDefinition => private var useRadius : Float = 0f //TODO belongs on a wider range of object definitions - private val targetValidation : mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean] = new mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean]() + private val targetValidation : mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject=>Boolean] = new mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject=>Boolean]() def UseRadius : Float = useRadius @@ -26,18 +26,14 @@ trait ProximityDefinition { UseRadius } - def TargetValidation : mutable.HashMap[ProximityTarget.Value, PlanetSideGameObject=>Boolean] = targetValidation + def TargetValidation : mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject=>Boolean] = targetValidation def Validations : Seq[PlanetSideGameObject=>Boolean] = { targetValidation.headOption match { case Some(_) => targetValidation.values.toSeq case None => - Seq(ProximityDefinition.Invalid) + Seq(EffectTarget.Validation.Invalid) } } } - -object ProximityDefinition { - protected val Invalid : PlanetSideGameObject=>Boolean = (_ : PlanetSideGameObject) => false -} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTarget.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTarget.scala deleted file mode 100644 index 9c02fba8..00000000 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTarget.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.objects.serverobject.terminals - -/** - * A classification of the target of this terminal's interactions. - * Arbitrary, but useful. - */ -object ProximityTarget extends Enumeration { - val - Aircraft, - Equipment, - Player, - Vehicle - = Value -} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 8fd7cc53..c7b2e742 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -126,35 +126,5 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor } object ProximityTerminalControl { - object Validation { - def Medical(target : PlanetSideGameObject) : Boolean = target match { - case p : Player => - p.Health > 0 && (p.Health < p.MaxHealth || p.Armor < p.MaxArmor) - case _ => - false - } - - def HealthCrystal(target : PlanetSideGameObject) : Boolean = target match { - case p : Player => - p.Health > 0 && p.Health < p.MaxHealth - case _ => - false - } - - def RepairSilo(target : PlanetSideGameObject) : Boolean = target match { - case v : Vehicle => - !GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth - case _ => - false - } - - def PadLanding(target : PlanetSideGameObject) : Boolean = target match { - case v : Vehicle => - GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth - case _ => - false - } - } - private case class TerminalAction() }