converted explosive-type and sensor-type deployables into complex deployables that have integrated control actors

This commit is contained in:
FateJH 2019-12-27 00:18:46 -05:00
parent 555ee35f8c
commit 879be93863
10 changed files with 300 additions and 143 deletions

View file

@ -1,9 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects package net.psforever.objects
import net.psforever.objects.definition.SimpleDeployableDefinition class BoomerDeployable(cdef : ExplosiveDeployableDefinition) extends ExplosiveDeployable(cdef) {
class BoomerDeployable(cdef : SimpleDeployableDefinition) extends ExplosiveDeployable(cdef) {
private var trigger : Option[BoomerTrigger] = None private var trigger : Option[BoomerTrigger] = None
def Trigger : Option[BoomerTrigger] = trigger def Trigger : Option[BoomerTrigger] = trigger

View file

@ -2,6 +2,12 @@
package net.psforever.objects package net.psforever.objects
import net.psforever.objects.ce.{Deployable, DeployedItem} 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 Deployables {
object Make { object Make {
@ -26,4 +32,43 @@ object Deployables {
DeployedItem.router_telepad_deployable -> { () => new TelepadDeployable(GlobalDefinitions.router_telepad_deployable) } DeployedItem.router_telepad_deployable -> { () => new TelepadDeployable(GlobalDefinitions.router_telepad_deployable) }
).withDefaultValue( { ()=> new ExplosiveDeployable(GlobalDefinitions.boomer) } ) ).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.<br>
* <br>
* 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))
}
} }

View file

@ -1,11 +1,22 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects package net.psforever.objects
import net.psforever.objects.ce.SimpleDeployable import akka.actor.{Actor, ActorContext, Props}
import net.psforever.objects.definition.SimpleDeployableDefinition 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.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 { with JammableUnit {
private var exploded : Boolean = false private var exploded : Boolean = false
@ -15,4 +26,86 @@ class ExplosiveDeployable(cdef : SimpleDeployableDefinition) extends SimpleDeplo
exploded = fuse exploded = fuse
Exploded 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))
}
}

View file

@ -870,11 +870,11 @@ object GlobalDefinitions {
/* /*
combat engineering deployables 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) val spitfire_turret = TurretDeployableDefinition(DeployedItem.spitfire_turret)
@ -882,9 +882,9 @@ object GlobalDefinitions {
val spitfire_aa = TurretDeployableDefinition(DeployedItem.spitfire_aa) 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) val tank_traps = SimpleDeployableDefinition(DeployedItem.tank_traps)
@ -5901,24 +5901,20 @@ object GlobalDefinitions {
boomer.MaxHealth = 100 boomer.MaxHealth = 100
boomer.DeployCategory = DeployableCategory.Boomers boomer.DeployCategory = DeployableCategory.Boomers
boomer.DeployTime = Duration.create(1000, "ms") boomer.DeployTime = Duration.create(1000, "ms")
boomer.Model = StandardResolutions.SimpleDeployables
he_mine.Name = "he_mine" he_mine.Name = "he_mine"
he_mine.Descriptor = "Mines" he_mine.Descriptor = "Mines"
he_mine.MaxHealth = 100 he_mine.MaxHealth = 100
he_mine.DeployCategory = DeployableCategory.Mines
he_mine.DeployTime = Duration.create(1000, "ms") he_mine.DeployTime = Duration.create(1000, "ms")
he_mine.Model = StandardResolutions.SimpleDeployables
jammer_mine.Name = "jammer_mine" jammer_mine.Name = "jammer_mine"
jammer_mine.Descriptor = "JammerMines" jammer_mine.Descriptor = "JammerMines"
jammer_mine.MaxHealth = 100 jammer_mine.MaxHealth = 100
jammer_mine.DeployCategory = DeployableCategory.Mines
jammer_mine.DeployTime = Duration.create(1000, "ms") jammer_mine.DeployTime = Duration.create(1000, "ms")
jammer_mine.Model = StandardResolutions.SimpleDeployables jammer_mine.DetonateOnJamming = false
spitfire_turret.Name = "spitfire_turret" spitfire_turret.Name = "spitfire_turret"
spitfire_turret.Descriptor= "Spitfires" spitfire_turret.Descriptor = "Spitfires"
spitfire_turret.MaxHealth = 100 spitfire_turret.MaxHealth = 100
spitfire_turret.Weapons += 1 -> new mutable.HashMap() spitfire_turret.Weapons += 1 -> new mutable.HashMap()
spitfire_turret.Weapons(1) += TurretUpgrade.None -> spitfire_weapon spitfire_turret.Weapons(1) += TurretUpgrade.None -> spitfire_weapon
@ -5928,7 +5924,7 @@ object GlobalDefinitions {
spitfire_turret.Model = StandardResolutions.ComplexDeployables spitfire_turret.Model = StandardResolutions.ComplexDeployables
spitfire_cloaked.Name = "spitfire_cloaked" spitfire_cloaked.Name = "spitfire_cloaked"
spitfire_cloaked.Descriptor= "CloakingSpitfires" spitfire_cloaked.Descriptor = "CloakingSpitfires"
spitfire_cloaked.MaxHealth = 100 spitfire_cloaked.MaxHealth = 100
spitfire_cloaked.Weapons += 1 -> new mutable.HashMap() spitfire_cloaked.Weapons += 1 -> new mutable.HashMap()
spitfire_cloaked.Weapons(1) += TurretUpgrade.None -> spitfire_weapon spitfire_cloaked.Weapons(1) += TurretUpgrade.None -> spitfire_weapon
@ -5938,7 +5934,7 @@ object GlobalDefinitions {
spitfire_cloaked.Model = StandardResolutions.ComplexDeployables spitfire_cloaked.Model = StandardResolutions.ComplexDeployables
spitfire_aa.Name = "spitfire_aa" spitfire_aa.Name = "spitfire_aa"
spitfire_aa.Descriptor= "FlakSpitfires" spitfire_aa.Descriptor = "FlakSpitfires"
spitfire_aa.MaxHealth = 100 spitfire_aa.MaxHealth = 100
spitfire_aa.Weapons += 1 -> new mutable.HashMap() spitfire_aa.Weapons += 1 -> new mutable.HashMap()
spitfire_aa.Weapons(1) += TurretUpgrade.None -> spitfire_aa_weapon spitfire_aa.Weapons(1) += TurretUpgrade.None -> spitfire_aa_weapon
@ -5950,16 +5946,12 @@ object GlobalDefinitions {
motionalarmsensor.Name = "motionalarmsensor" motionalarmsensor.Name = "motionalarmsensor"
motionalarmsensor.Descriptor = "MotionSensors" motionalarmsensor.Descriptor = "MotionSensors"
motionalarmsensor.MaxHealth = 100 motionalarmsensor.MaxHealth = 100
motionalarmsensor.DeployCategory = DeployableCategory.Sensors
motionalarmsensor.DeployTime = Duration.create(1000, "ms") motionalarmsensor.DeployTime = Duration.create(1000, "ms")
motionalarmsensor.Model = StandardResolutions.SimpleDeployables
sensor_shield.Name = "sensor_shield" sensor_shield.Name = "sensor_shield"
sensor_shield.Descriptor = "SensorShields" sensor_shield.Descriptor = "SensorShields"
sensor_shield.MaxHealth = 100 sensor_shield.MaxHealth = 100
sensor_shield.DeployCategory = DeployableCategory.Sensors
sensor_shield.DeployTime = Duration.create(5000, "ms") sensor_shield.DeployTime = Duration.create(5000, "ms")
sensor_shield.Model = StandardResolutions.SimpleDeployables
tank_traps.Name = "tank_traps" tank_traps.Name = "tank_traps"
tank_traps.Descriptor = "TankTraps" tank_traps.Descriptor = "TankTraps"

View file

@ -1,11 +1,129 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects package net.psforever.objects
import net.psforever.objects.ce.SimpleDeployable import akka.actor.{Actor, ActorContext, Props}
import net.psforever.objects.definition.SimpleDeployableDefinition import net.psforever.objects.ballistics.ResolvedProjectile
import net.psforever.objects.equipment.JammableUnit 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.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 Hackable
with JammableUnit 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))
}
}

View file

@ -11,14 +11,11 @@ import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.vital.Vitality import net.psforever.objects.vital.Vitality
import net.psforever.objects.zones.Zone 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.avatar.{AvatarAction, AvatarServiceMessage}
import services.local.{LocalAction, LocalServiceMessage} import services.Service
import services.{RemoverActor, Service}
import services.vehicle.{VehicleAction, VehicleServiceMessage} import services.vehicle.{VehicleAction, VehicleServiceMessage}
import scala.concurrent.duration.FiniteDuration
class ShieldGeneratorDeployable(cdef : ShieldGeneratorDefinition) extends ComplexDeployable(cdef) class ShieldGeneratorDeployable(cdef : ShieldGeneratorDefinition) extends ComplexDeployable(cdef)
with Hackable with Hackable
with JammableUnit with JammableUnit
@ -103,7 +100,7 @@ object ShieldGeneratorControl {
else { else {
HandleDestructionAwareness(target, playerGUID, cause) 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.ClearJammeredSound()
target.Actor ! JammableUnit.ClearJammeredStatus() target.Actor ! JammableUnit.ClearJammeredStatus()
val zone = target.Zone val zone = target.Zone
AnnounceDestroyDeployable(target, None) Deployables.AnnounceDestroyDeployable(target, None)
zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position)) 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))
}
} }

View file

@ -14,10 +14,9 @@ import net.psforever.objects.serverobject.mount.MountableBehavior
import net.psforever.objects.serverobject.turret.{TurretDefinition, WeaponTurret} import net.psforever.objects.serverobject.turret.{TurretDefinition, WeaponTurret}
import net.psforever.objects.vital.{StandardResolutions, StandardVehicleDamage, StandardVehicleResistance, Vitality} import net.psforever.objects.vital.{StandardResolutions, StandardVehicleDamage, StandardVehicleResistance, Vitality}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{DeployableInfo, DeploymentAction, PlanetSideGUID} import net.psforever.packet.game.PlanetSideGUID
import services.{RemoverActor, Service} import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage} import services.avatar.{AvatarAction, AvatarServiceMessage}
import services.local.{LocalAction, LocalServiceMessage}
import services.vehicle.{VehicleAction, VehicleServiceMessage} import services.vehicle.{VehicleAction, VehicleServiceMessage}
class TurretDeployable(tdef : TurretDeployableDefinition) extends ComplexDeployable(tdef) class TurretDeployable(tdef : TurretDeployableDefinition) extends ComplexDeployable(tdef)
@ -101,8 +100,6 @@ class TurretControl(turret : TurretDeployable) extends Actor
} }
object TurretControl { object TurretControl {
import scala.concurrent.duration._
/** /**
* na * na
* @param target na * @param target na
@ -178,24 +175,7 @@ object TurretControl {
val wep = slot.Equipment.get val wep = slot.Equipment.get
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID)) 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)) 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))
}
} }

View file

@ -3,7 +3,7 @@ package net.psforever.objects.vital.resolution
import net.psforever.objects.{Player, TurretDeployable, Vehicle} import net.psforever.objects.{Player, TurretDeployable, Vehicle}
import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile} 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.serverobject.turret.FacilityTurret
import net.psforever.objects.vital.projectile.ProjectileCalculations import net.psforever.objects.vital.projectile.ProjectileCalculations
@ -192,9 +192,9 @@ object ResolutionCalculations {
def SimpleApplication(damage : Int, data : ResolvedProjectile)(target : Any) : ResolvedProjectile = { def SimpleApplication(damage : Int, data : ResolvedProjectile)(target : Any) : ResolvedProjectile = {
target match { target match {
case ce : SimpleDeployable if ce.Health > 0 && damage > 0 => case obj : Deployable if obj.Health > 0 =>
ce.Health -= damage obj.Health -= damage
ce.History(data) obj.History(data)
case turret : FacilityTurret if turret.Health > 0 => case turret : FacilityTurret if turret.Health > 0 =>
turret.Health -= damage turret.Health -= damage
turret.History(data) turret.History(data)

View file

@ -7,7 +7,6 @@ import net.psforever.objects.serverobject.structures.{Amenity, Building}
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, Terminal} import net.psforever.objects.serverobject.terminals.{CaptureTerminal, Terminal}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.objects._ import net.psforever.objects._
import net.psforever.objects.equipment.JammableUnit
import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation} import net.psforever.packet.game.{PlanetSideGUID, TriggeredEffect, TriggeredEffectLocation}
import net.psforever.objects.vital.Vitality import net.psforever.objects.vital.Vitality
import net.psforever.types.Vector3 import net.psforever.types.Vector3
@ -287,19 +286,6 @@ class LocalService(zone : Zone) extends Actor {
} }
//synchronized damage calculations //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) => case Vitality.DamageOn(target : Deployable, damage_func) =>
val cause = damage_func(target) val cause = damage_func(target)
sender ! Vitality.DamageResolution(target, cause) sender ! Vitality.DamageResolution(target, cause)

View file

@ -915,10 +915,11 @@ class WorldSessionActor extends Actor
continent.Deployables ! Zone.Deployable.Dismiss(obj) continent.Deployables ! Zone.Deployable.Dismiss(obj)
} }
case WorldSessionActor.FinalizeDeployable(obj : ComplexDeployable, tool, index) => case WorldSessionActor.FinalizeDeployable(obj : SensorDeployable, tool, index) =>
//spitfires and deployable field turrets and the deployable_shield_generator //motion alarm sensor and sensor disruptor
StartBundlingPackets() StartBundlingPackets()
DeployableBuildActivity(obj) DeployableBuildActivity(obj)
continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.TriggerEffectInfo(player.GUID, "on", obj.GUID, true, 1000))
CommonDestroyConstructionItem(tool, index) CommonDestroyConstructionItem(tool, index)
FindReplacementConstructionItem(tool, index) FindReplacementConstructionItem(tool, index)
StopBundlingPackets() StopBundlingPackets()
@ -953,11 +954,10 @@ class WorldSessionActor extends Actor
FindReplacementConstructionItem(tool, index) FindReplacementConstructionItem(tool, index)
StopBundlingPackets() StopBundlingPackets()
case WorldSessionActor.FinalizeDeployable(obj : SensorDeployable, tool, index) => case WorldSessionActor.FinalizeDeployable(obj : ComplexDeployable, tool, index) =>
//motion alarm sensor and sensor disruptor //spitfires and deployable field turrets and the deployable_shield_generator
StartBundlingPackets() StartBundlingPackets()
DeployableBuildActivity(obj) DeployableBuildActivity(obj)
continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.TriggerEffectInfo(player.GUID, "on", obj.GUID, true, 1000))
CommonDestroyConstructionItem(tool, index) CommonDestroyConstructionItem(tool, index)
FindReplacementConstructionItem(tool, index) FindReplacementConstructionItem(tool, index)
StopBundlingPackets() StopBundlingPackets()
@ -1107,43 +1107,8 @@ class WorldSessionActor extends Actor
AnnounceDestroyDeployable(target, None) AnnounceDestroyDeployable(target, None)
} }
case Vitality.DamageResolution(target : SensorDeployable, _) => case Vitality.DamageResolution(target : TelepadDeployable, _) =>
//sensors //telepads
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
if(target.Health <= 0) { if(target.Health <= 0) {
//update if destroyed //update if destroyed
val guid = target.GUID 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) 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) => case LocalResponse.EliminateDeployable(obj : ExplosiveDeployable, guid, pos) =>
if(obj.Exploded || obj.Jammed || obj.Health == 0) { if(obj.Exploded || obj.Jammed || obj.Health == 0) {
DeconstructDeployable(obj, guid, pos) DeconstructDeployable(obj, guid, pos)
@ -1596,6 +1553,14 @@ class WorldSessionActor extends Actor
DeconstructDeployable(obj, guid, pos, obj.Orientation, 2) 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) => case LocalResponse.EliminateDeployable(obj : TelepadDeployable, guid, pos) =>
//if active, deactivate //if active, deactivate
if(obj.Active) { if(obj.Active) {
@ -4234,7 +4199,7 @@ class WorldSessionActor extends Actor
case Some(boomer : BoomerDeployable) => case Some(boomer : BoomerDeployable) =>
boomer.Exploded = true boomer.Exploded = true
continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.Detonate(boomer.GUID, boomer)) continent.LocalEvents ! LocalServiceMessage(continent.Id, LocalAction.Detonate(boomer.GUID, boomer))
AnnounceDestroyDeployable(boomer, Some(500 milliseconds)) Deployables.AnnounceDestroyDeployable(boomer, Some(500 milliseconds))
case Some(_) | None => ; case Some(_) | None => ;
} }
FindEquipmentToDelete(item_guid, trigger) FindEquipmentToDelete(item_guid, trigger)