diff --git a/common/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/common/src/main/scala/net/psforever/objects/BoomerDeployable.scala
index 21d66ea2..39523d25 100644
--- a/common/src/main/scala/net/psforever/objects/BoomerDeployable.scala
+++ b/common/src/main/scala/net/psforever/objects/BoomerDeployable.scala
@@ -1,9 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
-import net.psforever.objects.definition.SimpleDeployableDefinition
-
-class BoomerDeployable(cdef : SimpleDeployableDefinition) extends ExplosiveDeployable(cdef) {
+class BoomerDeployable(cdef : ExplosiveDeployableDefinition) extends ExplosiveDeployable(cdef) {
private var trigger : Option[BoomerTrigger] = None
def Trigger : Option[BoomerTrigger] = trigger
diff --git a/common/src/main/scala/net/psforever/objects/Deployables.scala b/common/src/main/scala/net/psforever/objects/Deployables.scala
index de1c9ce0..3c0af9b0 100644
--- a/common/src/main/scala/net/psforever/objects/Deployables.scala
+++ b/common/src/main/scala/net/psforever/objects/Deployables.scala
@@ -2,6 +2,12 @@
package net.psforever.objects
import net.psforever.objects.ce.{Deployable, DeployedItem}
+import net.psforever.objects.serverobject.PlanetSideServerObject
+import net.psforever.packet.game.{DeployableInfo, DeploymentAction, PlanetSideGUID}
+import services.RemoverActor
+import services.local.{LocalAction, LocalServiceMessage}
+
+import scala.concurrent.duration.FiniteDuration
object Deployables {
object Make {
@@ -26,4 +32,43 @@ object Deployables {
DeployedItem.router_telepad_deployable -> { () => new TelepadDeployable(GlobalDefinitions.router_telepad_deployable) }
).withDefaultValue( { ()=> new ExplosiveDeployable(GlobalDefinitions.boomer) } )
}
+
+ /**
+ * Distribute information that a deployable has been destroyed.
+ * The deployable may not have yet been eliminated from the game world (client or server),
+ * but its health is zero and it has entered the conditions where it is nearly irrelevant.
+ *
+ * The typical use case of this function involves destruction via weapon fire, attributed to a particular player.
+ * Contrast this to simply destroying a deployable by being the deployable's owner and using the map icon controls.
+ * This function eventually invokes the same routine
+ * but mainly goes into effect when the deployable has been destroyed
+ * and may still leave a physical component in the game world to be cleaned up later.
+ * That is the task `EliminateDeployable` performs.
+ * Additionally, since the player who destroyed the deployable isn't necessarily the owner,
+ * and the real owner will still be aware of the existence of the deployable,
+ * that player must be informed of the loss of the deployable directly.
+ * @see `DeployableRemover`
+ * @see `Vitality.DamageResolution`
+ * @see `LocalResponse.EliminateDeployable`
+ * @see `DeconstructDeployable`
+ * @param target the deployable that is destroyed
+ * @param time length of time that the deployable is allowed to exist in the game world;
+ * `None` indicates the normal un-owned existence time (180 seconds)
+ */
+ def AnnounceDestroyDeployable(target : PlanetSideServerObject with Deployable, time : Option[FiniteDuration]) : Unit = {
+ val zone = target.Zone
+ target.OwnerName match {
+ case Some(owner) =>
+ target.OwnerName = None
+ zone.LocalEvents ! LocalServiceMessage(owner, LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target))
+ case None => ;
+ }
+ zone.LocalEvents ! LocalServiceMessage(s"${target.Faction}", LocalAction.DeployableMapIcon(
+ PlanetSideGUID(0),
+ DeploymentAction.Dismiss,
+ DeployableInfo(target.GUID, Deployable.Icon(target.Definition.Item), target.Position, PlanetSideGUID(0)))
+ )
+ zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.ClearSpecific(List(target), zone))
+ zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.AddTask(target, zone, time))
+ }
}
diff --git a/common/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala b/common/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala
index b324c666..75482ecb 100644
--- a/common/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala
+++ b/common/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala
@@ -1,11 +1,22 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
-import net.psforever.objects.ce.SimpleDeployable
-import net.psforever.objects.definition.SimpleDeployableDefinition
+import akka.actor.{Actor, ActorContext, Props}
+import net.psforever.objects.ballistics.ResolvedProjectile
+import net.psforever.objects.ce._
+import net.psforever.objects.definition.{ComplexDeployableDefinition, SimpleDeployableDefinition}
+import net.psforever.objects.definition.converter.SmallDeployableConverter
import net.psforever.objects.equipment.JammableUnit
+import net.psforever.objects.serverobject.PlanetSideServerObject
+import net.psforever.objects.vital.{StandardResolutions, Vitality}
+import net.psforever.packet.game.PlanetSideGUID
+import net.psforever.types.Vector3
+import services.avatar.{AvatarAction, AvatarServiceMessage}
+import services.local.{LocalAction, LocalServiceMessage}
-class ExplosiveDeployable(cdef : SimpleDeployableDefinition) extends SimpleDeployable(cdef)
+import scala.concurrent.duration._
+
+class ExplosiveDeployable(cdef : ExplosiveDeployableDefinition) extends ComplexDeployable(cdef)
with JammableUnit {
private var exploded : Boolean = false
@@ -15,4 +26,86 @@ class ExplosiveDeployable(cdef : SimpleDeployableDefinition) extends SimpleDeplo
exploded = fuse
Exploded
}
+
+ override def Definition : ExplosiveDeployableDefinition = cdef
}
+
+class ExplosiveDeployableDefinition(private val objectId : Int) extends ComplexDeployableDefinition(objectId) {
+ Name = "explosive_deployable"
+ DeployCategory = DeployableCategory.Mines
+ Model = StandardResolutions.SimpleDeployables
+ Packet = new SmallDeployableConverter
+
+ private var detonateOnJamming : Boolean = true
+
+ def DetonateOnJamming : Boolean = detonateOnJamming
+
+ def DetonateOnJamming_=(detonate : Boolean) : Boolean = {
+ detonateOnJamming = detonate
+ DetonateOnJamming
+ }
+
+ override def Initialize(obj : PlanetSideServerObject with Deployable, context : ActorContext) = {
+ obj.Actor = context.actorOf(Props(classOf[ExplosiveDeployableControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
+ }
+
+ override def Uninitialize(obj : PlanetSideServerObject with Deployable, context : ActorContext) = {
+ SimpleDeployableDefinition.SimpleUninitialize(obj, context)
+ }
+}
+
+object ExplosiveDeployableDefinition {
+ def apply(dtype : DeployedItem.Value) : ExplosiveDeployableDefinition = {
+ new ExplosiveDeployableDefinition(dtype.id)
+ }
+}
+
+class ExplosiveDeployableControl(mine : ExplosiveDeployable) extends Actor {
+ def receive : Receive = {
+ case Vitality.Damage(damage_func) =>
+ val originalHealth = mine.Health
+ if(originalHealth > 0) {
+ val cause = damage_func(mine)
+ ExplosiveDeployableControl.HandleDamageResolution(mine, cause, originalHealth - mine.Health)
+ }
+
+ case _ => ;
+ }
+}
+
+object ExplosiveDeployableControl {
+ def HandleDamageResolution(target : ExplosiveDeployable, cause : ResolvedProjectile, damage : Int) : Unit = {
+ val zone = target.Zone
+ val playerGUID = zone.LivePlayers.find { p => cause.projectile.owner.Name.equals(p.Name) } match {
+ case Some(player) => player.GUID
+ case _ => PlanetSideGUID(0)
+ }
+ if(target.Health == 0) {
+ HandleDestructionAwareness(target, playerGUID, cause)
+ }
+ else if(!target.Jammed && cause.projectile.profile.JammerProjectile) {
+ if(target.Jammed = {
+ val radius = cause.projectile.profile.DamageRadius
+ Vector3.DistanceSquared(cause.hit_pos, cause.target.Position) < radius * radius
+ }) {
+ if(target.Definition.DetonateOnJamming) {
+ target.Zone.LocalEvents ! LocalServiceMessage(target.Zone.Id, LocalAction.Detonate(target.GUID, target))
+ }
+ HandleDestructionAwareness(target, playerGUID, cause)
+ }
+ }
+ }
+
+ /**
+ * na
+ * @param target na
+ * @param attribution na
+ * @param lastShot na
+ */
+ def HandleDestructionAwareness(target : ExplosiveDeployable, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
+ val zone = target.Zone
+ Deployables.AnnounceDestroyDeployable(target, Some(if(target.Jammed) 0 seconds else 500 milliseconds))
+ zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
+ }
+}
+
diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
index 13066bd9..af18d1f7 100644
--- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
+++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
@@ -870,11 +870,11 @@ object GlobalDefinitions {
/*
combat engineering deployables
*/
- val boomer = SimpleDeployableDefinition(DeployedItem.boomer)
+ val boomer = ExplosiveDeployableDefinition(DeployedItem.boomer)
- val he_mine = SimpleDeployableDefinition(DeployedItem.he_mine)
+ val he_mine = ExplosiveDeployableDefinition(DeployedItem.he_mine)
- val jammer_mine = SimpleDeployableDefinition(DeployedItem.jammer_mine)
+ val jammer_mine = ExplosiveDeployableDefinition(DeployedItem.jammer_mine)
val spitfire_turret = TurretDeployableDefinition(DeployedItem.spitfire_turret)
@@ -882,9 +882,9 @@ object GlobalDefinitions {
val spitfire_aa = TurretDeployableDefinition(DeployedItem.spitfire_aa)
- val motionalarmsensor = SimpleDeployableDefinition(DeployedItem.motionalarmsensor)
+ val motionalarmsensor = SensorDeployableDefinition(DeployedItem.motionalarmsensor)
- val sensor_shield = SimpleDeployableDefinition(DeployedItem.sensor_shield)
+ val sensor_shield = SensorDeployableDefinition(DeployedItem.sensor_shield)
val tank_traps = SimpleDeployableDefinition(DeployedItem.tank_traps)
@@ -5901,24 +5901,20 @@ object GlobalDefinitions {
boomer.MaxHealth = 100
boomer.DeployCategory = DeployableCategory.Boomers
boomer.DeployTime = Duration.create(1000, "ms")
- boomer.Model = StandardResolutions.SimpleDeployables
he_mine.Name = "he_mine"
he_mine.Descriptor = "Mines"
he_mine.MaxHealth = 100
- he_mine.DeployCategory = DeployableCategory.Mines
he_mine.DeployTime = Duration.create(1000, "ms")
- he_mine.Model = StandardResolutions.SimpleDeployables
jammer_mine.Name = "jammer_mine"
jammer_mine.Descriptor = "JammerMines"
jammer_mine.MaxHealth = 100
- jammer_mine.DeployCategory = DeployableCategory.Mines
jammer_mine.DeployTime = Duration.create(1000, "ms")
- jammer_mine.Model = StandardResolutions.SimpleDeployables
+ jammer_mine.DetonateOnJamming = false
spitfire_turret.Name = "spitfire_turret"
- spitfire_turret.Descriptor= "Spitfires"
+ spitfire_turret.Descriptor = "Spitfires"
spitfire_turret.MaxHealth = 100
spitfire_turret.Weapons += 1 -> new mutable.HashMap()
spitfire_turret.Weapons(1) += TurretUpgrade.None -> spitfire_weapon
@@ -5928,7 +5924,7 @@ object GlobalDefinitions {
spitfire_turret.Model = StandardResolutions.ComplexDeployables
spitfire_cloaked.Name = "spitfire_cloaked"
- spitfire_cloaked.Descriptor= "CloakingSpitfires"
+ spitfire_cloaked.Descriptor = "CloakingSpitfires"
spitfire_cloaked.MaxHealth = 100
spitfire_cloaked.Weapons += 1 -> new mutable.HashMap()
spitfire_cloaked.Weapons(1) += TurretUpgrade.None -> spitfire_weapon
@@ -5938,7 +5934,7 @@ object GlobalDefinitions {
spitfire_cloaked.Model = StandardResolutions.ComplexDeployables
spitfire_aa.Name = "spitfire_aa"
- spitfire_aa.Descriptor= "FlakSpitfires"
+ spitfire_aa.Descriptor = "FlakSpitfires"
spitfire_aa.MaxHealth = 100
spitfire_aa.Weapons += 1 -> new mutable.HashMap()
spitfire_aa.Weapons(1) += TurretUpgrade.None -> spitfire_aa_weapon
@@ -5950,16 +5946,12 @@ object GlobalDefinitions {
motionalarmsensor.Name = "motionalarmsensor"
motionalarmsensor.Descriptor = "MotionSensors"
motionalarmsensor.MaxHealth = 100
- motionalarmsensor.DeployCategory = DeployableCategory.Sensors
motionalarmsensor.DeployTime = Duration.create(1000, "ms")
- motionalarmsensor.Model = StandardResolutions.SimpleDeployables
sensor_shield.Name = "sensor_shield"
sensor_shield.Descriptor = "SensorShields"
sensor_shield.MaxHealth = 100
- sensor_shield.DeployCategory = DeployableCategory.Sensors
sensor_shield.DeployTime = Duration.create(5000, "ms")
- sensor_shield.Model = StandardResolutions.SimpleDeployables
tank_traps.Name = "tank_traps"
tank_traps.Descriptor = "TankTraps"
diff --git a/common/src/main/scala/net/psforever/objects/SensorDeployable.scala b/common/src/main/scala/net/psforever/objects/SensorDeployable.scala
index 1c886cd9..71d3373a 100644
--- a/common/src/main/scala/net/psforever/objects/SensorDeployable.scala
+++ b/common/src/main/scala/net/psforever/objects/SensorDeployable.scala
@@ -1,11 +1,129 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
-import net.psforever.objects.ce.SimpleDeployable
-import net.psforever.objects.definition.SimpleDeployableDefinition
-import net.psforever.objects.equipment.JammableUnit
+import akka.actor.{Actor, ActorContext, Props}
+import net.psforever.objects.ballistics.ResolvedProjectile
+import net.psforever.objects.ce._
+import net.psforever.objects.definition.converter.SmallDeployableConverter
+import net.psforever.objects.definition.{ComplexDeployableDefinition, SimpleDeployableDefinition}
+import net.psforever.objects.equipment.{JammableBehavior, JammableUnit}
+import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.hackable.Hackable
+import net.psforever.objects.vital.{StandardResolutions, Vitality}
+import net.psforever.objects.zones.Zone
+import net.psforever.packet.game.PlanetSideGUID
+import services.Service
+import services.avatar.{AvatarAction, AvatarServiceMessage}
+import services.local.{LocalAction, LocalServiceMessage}
+import services.vehicle.{VehicleAction, VehicleServiceMessage}
-class SensorDeployable(cdef : SimpleDeployableDefinition) extends SimpleDeployable(cdef)
+import scala.concurrent.duration._
+
+class SensorDeployable(cdef : SensorDeployableDefinition) extends ComplexDeployable(cdef)
with Hackable
with JammableUnit
+
+class SensorDeployableDefinition(private val objectId : Int) extends ComplexDeployableDefinition(objectId) {
+ Name = "sensor_deployable"
+ DeployCategory = DeployableCategory.Sensors
+ Model = StandardResolutions.SimpleDeployables
+ Packet = new SmallDeployableConverter
+
+ override def Initialize(obj : PlanetSideServerObject with Deployable, context : ActorContext) = {
+ obj.Actor = context.actorOf(Props(classOf[SensorDeployableControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
+ }
+
+ override def Uninitialize(obj : PlanetSideServerObject with Deployable, context : ActorContext) = {
+ SimpleDeployableDefinition.SimpleUninitialize(obj, context)
+ }
+}
+
+object SensorDeployableDefinition {
+ def apply(dtype : DeployedItem.Value) : SensorDeployableDefinition = {
+ new SensorDeployableDefinition(dtype.id)
+ }
+}
+
+class SensorDeployableControl(sensor : SensorDeployable) extends Actor
+ with JammableBehavior {
+
+ def JammableObject = sensor
+
+ def receive : Receive = jammableBehavior.orElse {
+ case Vitality.Damage(damage_func) =>
+ val originalHealth = sensor.Health
+ if(originalHealth > 0) {
+ val cause = damage_func(sensor)
+ SensorDeployableControl.HandleDamageResolution(sensor, cause, originalHealth - sensor.Health)
+ }
+
+ case _ => ;
+ }
+
+ override def StartJammeredSound(target : Any, dur : Int) : Unit = target match {
+ case obj : PlanetSideServerObject =>
+ obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 1))
+ super.StartJammeredSound(obj, dur)
+ case _ => ;
+ }
+
+ override def StartJammeredStatus(target : Any, dur : Int) : Unit = target match {
+ case obj : PlanetSideServerObject =>
+ sensor.Zone.LocalEvents ! LocalServiceMessage(sensor.Zone.Id, LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, false, 1000))
+ super.StartJammeredStatus(obj, dur)
+ case _ => ;
+ }
+
+ override def CancelJammeredSound(target : Any) : Unit = target match {
+ case obj : PlanetSideServerObject =>
+ obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 0))
+ super.CancelJammeredSound(obj)
+ case _ => ;
+ }
+
+ override def CancelJammeredStatus(target : Any) : Unit = target match {
+ case obj : PlanetSideServerObject =>
+ sensor.Zone.LocalEvents ! LocalServiceMessage(sensor.Zone.Id, LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, true, 1000))
+ super.CancelJammeredStatus(obj)
+ case _ => ;
+ }
+}
+
+object SensorDeployableControl {
+ def HandleDamageResolution(target : SensorDeployable, cause : ResolvedProjectile, damage : Int) : Unit = {
+ val zone = target.Zone
+ val targetGUID = target.GUID
+ val playerGUID = zone.LivePlayers.find { p => cause.projectile.owner.Name.equals(p.Name) } match {
+ case Some(player) => player.GUID
+ case _ => PlanetSideGUID(0)
+ }
+ if(target.Health > 0) {
+ //activity on map
+ if(damage > 0) {
+ zone.Activity ! Zone.HotSpot.Activity(cause.target, cause.projectile.owner, cause.hit_pos)
+ }
+ if(cause.projectile.profile.JammerProjectile) {
+ target.Actor ! JammableUnit.Jammered(cause)
+ }
+ }
+ else {
+ HandleDestructionAwareness(target, playerGUID, cause)
+ }
+ zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.PlanetsideAttribute(targetGUID, 0, target.Health))
+ }
+
+ /**
+ * na
+ * @param target na
+ * @param attribution na
+ * @param lastShot na
+ */
+ def HandleDestructionAwareness(target : SensorDeployable, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
+ target.Actor ! JammableUnit.ClearJammeredSound()
+ target.Actor ! JammableUnit.ClearJammeredStatus()
+ val zone = target.Zone
+ Deployables.AnnounceDestroyDeployable(target, Some(0 seconds))
+ zone.LocalEvents ! LocalServiceMessage(zone.Id, LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", target.GUID, false, 1000))
+ zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
+ }
+}
diff --git a/common/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala b/common/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala
index ffe8dcb1..d304bb93 100644
--- a/common/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala
+++ b/common/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala
@@ -11,14 +11,11 @@ import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.vital.Vitality
import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{DeployableInfo, DeploymentAction, PlanetSideGUID}
+import net.psforever.packet.game.PlanetSideGUID
import services.avatar.{AvatarAction, AvatarServiceMessage}
-import services.local.{LocalAction, LocalServiceMessage}
-import services.{RemoverActor, Service}
+import services.Service
import services.vehicle.{VehicleAction, VehicleServiceMessage}
-import scala.concurrent.duration.FiniteDuration
-
class ShieldGeneratorDeployable(cdef : ShieldGeneratorDefinition) extends ComplexDeployable(cdef)
with Hackable
with JammableUnit
@@ -103,7 +100,7 @@ object ShieldGeneratorControl {
else {
HandleDestructionAwareness(target, playerGUID, cause)
}
- zone.VehicleEvents ! VehicleServiceMessage(zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.Health))
+ zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.PlanetsideAttribute(targetGUID, 0, target.Health))
}
/**
@@ -116,24 +113,7 @@ object ShieldGeneratorControl {
target.Actor ! JammableUnit.ClearJammeredSound()
target.Actor ! JammableUnit.ClearJammeredStatus()
val zone = target.Zone
- AnnounceDestroyDeployable(target, None)
+ Deployables.AnnounceDestroyDeployable(target, None)
zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
}
-
- def AnnounceDestroyDeployable(target : PlanetSideServerObject with Deployable, time : Option[FiniteDuration]) : Unit = {
- val zone = target.Zone
- target.OwnerName match {
- case Some(owner) =>
- target.OwnerName = None
- zone.LocalEvents ! LocalServiceMessage(owner, LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target))
- case None => ;
- }
- zone.LocalEvents ! LocalServiceMessage(s"${target.Faction}", LocalAction.DeployableMapIcon(
- PlanetSideGUID(0),
- DeploymentAction.Dismiss,
- DeployableInfo(target.GUID, Deployable.Icon(target.Definition.Item), target.Position, PlanetSideGUID(0)))
- )
- zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.ClearSpecific(List(target), zone))
- zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.AddTask(target, zone, time))
- }
}
diff --git a/common/src/main/scala/net/psforever/objects/TurretDeployable.scala b/common/src/main/scala/net/psforever/objects/TurretDeployable.scala
index 23b57441..46d9601a 100644
--- a/common/src/main/scala/net/psforever/objects/TurretDeployable.scala
+++ b/common/src/main/scala/net/psforever/objects/TurretDeployable.scala
@@ -14,10 +14,9 @@ import net.psforever.objects.serverobject.mount.MountableBehavior
import net.psforever.objects.serverobject.turret.{TurretDefinition, WeaponTurret}
import net.psforever.objects.vital.{StandardResolutions, StandardVehicleDamage, StandardVehicleResistance, Vitality}
import net.psforever.objects.zones.Zone
-import net.psforever.packet.game.{DeployableInfo, DeploymentAction, PlanetSideGUID}
-import services.{RemoverActor, Service}
+import net.psforever.packet.game.PlanetSideGUID
+import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage}
-import services.local.{LocalAction, LocalServiceMessage}
import services.vehicle.{VehicleAction, VehicleServiceMessage}
class TurretDeployable(tdef : TurretDeployableDefinition) extends ComplexDeployable(tdef)
@@ -101,8 +100,6 @@ class TurretControl(turret : TurretDeployable) extends Actor
}
object TurretControl {
- import scala.concurrent.duration._
-
/**
* na
* @param target na
@@ -178,24 +175,7 @@ object TurretControl {
val wep = slot.Equipment.get
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
})
- AnnounceDestroyDeployable(target, None)
+ Deployables.AnnounceDestroyDeployable(target, None)
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
}
-
- def AnnounceDestroyDeployable(target : PlanetSideServerObject with Deployable, time : Option[FiniteDuration]) : Unit = {
- val zone = target.Zone
- target.OwnerName match {
- case Some(owner) =>
- target.OwnerName = None
- zone.LocalEvents ! LocalServiceMessage(owner, LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target))
- case None => ;
- }
- zone.LocalEvents ! LocalServiceMessage(s"${target.Faction}", LocalAction.DeployableMapIcon(
- PlanetSideGUID(0),
- DeploymentAction.Dismiss,
- DeployableInfo(target.GUID, Deployable.Icon(target.Definition.Item), target.Position, PlanetSideGUID(0)))
- )
- zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.ClearSpecific(List(target), zone))
- zone.LocalEvents ! LocalServiceMessage.Deployables(RemoverActor.AddTask(target, zone, time))
- }
}
diff --git a/common/src/main/scala/net/psforever/objects/vital/resolution/ResolutionCalculations.scala b/common/src/main/scala/net/psforever/objects/vital/resolution/ResolutionCalculations.scala
index a85f6206..bd395792 100644
--- a/common/src/main/scala/net/psforever/objects/vital/resolution/ResolutionCalculations.scala
+++ b/common/src/main/scala/net/psforever/objects/vital/resolution/ResolutionCalculations.scala
@@ -3,7 +3,7 @@ package net.psforever.objects.vital.resolution
import net.psforever.objects.{Player, TurretDeployable, Vehicle}
import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile}
-import net.psforever.objects.ce.{ComplexDeployable, SimpleDeployable}
+import net.psforever.objects.ce.{ComplexDeployable, Deployable}
import net.psforever.objects.serverobject.turret.FacilityTurret
import net.psforever.objects.vital.projectile.ProjectileCalculations
@@ -192,9 +192,9 @@ object ResolutionCalculations {
def SimpleApplication(damage : Int, data : ResolvedProjectile)(target : Any) : ResolvedProjectile = {
target match {
- case ce : SimpleDeployable if ce.Health > 0 && damage > 0 =>
- ce.Health -= damage
- ce.History(data)
+ case obj : Deployable if obj.Health > 0 =>
+ obj.Health -= damage
+ obj.History(data)
case turret : FacilityTurret if turret.Health > 0 =>
turret.Health -= damage
turret.History(data)
diff --git a/common/src/main/scala/services/local/LocalService.scala b/common/src/main/scala/services/local/LocalService.scala
index 21b137c8..369e653b 100644
--- a/common/src/main/scala/services/local/LocalService.scala
+++ b/common/src/main/scala/services/local/LocalService.scala
@@ -7,7 +7,6 @@ import net.psforever.objects.serverobject.structures.{Amenity, Building}
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, Terminal}
import net.psforever.objects.zones.Zone
import net.psforever.objects._
-import net.psforever.objects.equipment.JammableUnit
import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation}
import net.psforever.objects.vital.Vitality
import net.psforever.types.Vector3
@@ -287,19 +286,6 @@ class LocalService(zone : Zone) extends Actor {
}
//synchronized damage calculations
- case Vitality.DamageOn(target : Deployable with JammableUnit, damage_func) =>
- if(target.Health > 0) {
- val cause = damage_func(target)
- target.Jammed = if(cause.projectile.profile.JammerProjectile) {
- val radius = cause.projectile.profile.DamageRadius
- Vector3.DistanceSquared(cause.hit_pos, cause.target.Position) < radius * radius
- }
- else {
- false
- }
- sender ! Vitality.DamageResolution(target, cause)
- }
-
case Vitality.DamageOn(target : Deployable, damage_func) =>
val cause = damage_func(target)
sender ! Vitality.DamageResolution(target, cause)
diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala
index e2dd5569..5f2a7ab6 100644
--- a/pslogin/src/main/scala/WorldSessionActor.scala
+++ b/pslogin/src/main/scala/WorldSessionActor.scala
@@ -915,10 +915,11 @@ class WorldSessionActor extends Actor
continent.Deployables ! Zone.Deployable.Dismiss(obj)
}
- case WorldSessionActor.FinalizeDeployable(obj : ComplexDeployable, tool, index) =>
- //spitfires and deployable field turrets and the deployable_shield_generator
+ case WorldSessionActor.FinalizeDeployable(obj : SensorDeployable, tool, index) =>
+ //motion alarm sensor and sensor disruptor
StartBundlingPackets()
DeployableBuildActivity(obj)
+ continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.TriggerEffectInfo(player.GUID, "on", obj.GUID, true, 1000))
CommonDestroyConstructionItem(tool, index)
FindReplacementConstructionItem(tool, index)
StopBundlingPackets()
@@ -953,11 +954,10 @@ class WorldSessionActor extends Actor
FindReplacementConstructionItem(tool, index)
StopBundlingPackets()
- case WorldSessionActor.FinalizeDeployable(obj : SensorDeployable, tool, index) =>
- //motion alarm sensor and sensor disruptor
+ case WorldSessionActor.FinalizeDeployable(obj : ComplexDeployable, tool, index) =>
+ //spitfires and deployable field turrets and the deployable_shield_generator
StartBundlingPackets()
DeployableBuildActivity(obj)
- continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.TriggerEffectInfo(player.GUID, "on", obj.GUID, true, 1000))
CommonDestroyConstructionItem(tool, index)
FindReplacementConstructionItem(tool, index)
StopBundlingPackets()
@@ -1107,43 +1107,8 @@ class WorldSessionActor extends Actor
AnnounceDestroyDeployable(target, None)
}
- case Vitality.DamageResolution(target : SensorDeployable, _) =>
- //sensors
- val guid = target.GUID
- val health = target.Health
- continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(guid, 0, health))
- if(health <= 0) {
- AnnounceDestroyDeployable(target, Some(0 seconds))
- }
-
- case Vitality.DamageResolution(target : BoomerDeployable, _) =>
- //boomer
- if(target.Jammed) {
- continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.Detonate(target.GUID, target))
- AnnounceDestroyDeployable(target, Some(500 milliseconds))
- }
- else if(target.Health <= 0) {
- AnnounceDestroyDeployable(target, Some(0 seconds))
- }
-
- case Vitality.DamageResolution(target : ExplosiveDeployable, _) if target.Definition eq he_mine =>
- //he_mine
- if(target.Jammed) {
- continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.Detonate(target.GUID, target))
- AnnounceDestroyDeployable(target, Some(500 milliseconds))
- }
- else if(target.Health <= 0) {
- AnnounceDestroyDeployable(target, Some(0 seconds))
- }
-
- case Vitality.DamageResolution(target : ExplosiveDeployable, _) if target.Definition eq jammer_mine =>
- //jammer_mine
- if(target.Jammed || target.Health <= 0) {
- AnnounceDestroyDeployable(target, Some(0 seconds))
- }
-
- case Vitality.DamageResolution(target : SimpleDeployable, _) =>
- //boomers, mines
+ case Vitality.DamageResolution(target : TelepadDeployable, _) =>
+ //telepads
if(target.Health <= 0) {
//update if destroyed
val guid = target.GUID
@@ -1580,14 +1545,6 @@ class WorldSessionActor extends Actor
DeconstructDeployable(obj, guid, pos, obj.Orientation, if(obj.MountPoints.isEmpty) 2 else 1)
}
- case LocalResponse.EliminateDeployable(obj : ComplexDeployable, guid, pos) =>
- if(obj.Health == 0) {
- DeconstructDeployable(obj, guid, pos)
- }
- else {
- DeconstructDeployable(obj, guid, pos, obj.Orientation, 1)
- }
-
case LocalResponse.EliminateDeployable(obj : ExplosiveDeployable, guid, pos) =>
if(obj.Exploded || obj.Jammed || obj.Health == 0) {
DeconstructDeployable(obj, guid, pos)
@@ -1596,6 +1553,14 @@ class WorldSessionActor extends Actor
DeconstructDeployable(obj, guid, pos, obj.Orientation, 2)
}
+ case LocalResponse.EliminateDeployable(obj : ComplexDeployable, guid, pos) =>
+ if(obj.Health == 0) {
+ DeconstructDeployable(obj, guid, pos)
+ }
+ else {
+ DeconstructDeployable(obj, guid, pos, obj.Orientation, 1)
+ }
+
case LocalResponse.EliminateDeployable(obj : TelepadDeployable, guid, pos) =>
//if active, deactivate
if(obj.Active) {
@@ -4234,7 +4199,7 @@ class WorldSessionActor extends Actor
case Some(boomer : BoomerDeployable) =>
boomer.Exploded = true
continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.Detonate(boomer.GUID, boomer))
- AnnounceDestroyDeployable(boomer, Some(500 milliseconds))
+ Deployables.AnnounceDestroyDeployable(boomer, Some(500 milliseconds))
case Some(_) | None => ;
}
FindEquipmentToDelete(item_guid, trigger)