mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
proper jamming behavior for facility turrets; moved certain facility turret operations onto FacilityTurretControl actor; corrected issue with revisiting jammed status
This commit is contained in:
parent
bb26c5d56e
commit
fa2123f253
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.equipment
|
||||
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.ballistics.ResolvedProjectile
|
||||
import net.psforever.objects.serverobject.terminals.TargetValidation
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -19,6 +20,12 @@ trait JammableUnit {
|
|||
|
||||
object JammableUnit {
|
||||
final case class Jammer()
|
||||
|
||||
final case class Jammered(cause : ResolvedProjectile)
|
||||
|
||||
final case class ClearJammeredSound()
|
||||
|
||||
final case class ClearJammeredStatus()
|
||||
}
|
||||
|
||||
trait JammingUnit {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.turret
|
||||
|
||||
import akka.actor.Actor
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.{DefaultCancellable, Tool}
|
||||
import net.psforever.objects.ballistics.ResolvedProjectile
|
||||
import net.psforever.objects.equipment.{JammableUnit, JammingUnit}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.vehicles.MountedWeapons
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.Vector3
|
||||
import services.Service
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import services.vehicle.support.TurretUpgrader
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `MannedTurret`.<br>
|
||||
|
|
@ -17,6 +31,9 @@ import net.psforever.objects.vital.Vitality
|
|||
class FacilityTurretControl(turret : FacilityTurret) extends Actor
|
||||
with FactionAffinityBehavior.Check
|
||||
with MountableBehavior.Dismount {
|
||||
var jammeredSoundTimer : Cancellable = DefaultCancellable.obj
|
||||
var jammeredStatusTimer : Cancellable = DefaultCancellable.obj
|
||||
|
||||
def MountableObject = turret //do not add type!
|
||||
|
||||
def FactionObject : FactionAffinity = turret
|
||||
|
|
@ -45,12 +62,149 @@ class FacilityTurretControl(turret : FacilityTurret) extends Actor
|
|||
val cause = damage_func(turret)
|
||||
val health = turret.Health
|
||||
val damageToHealth = originalHealth - health
|
||||
val name = turret.Actor.toString
|
||||
val slashPoint = name.lastIndexOf("/")
|
||||
org.log4s.getLogger("DamageResolution").info(s"${name.substring(slashPoint+1, name.length-1)}: BEFORE=$originalHealth, AFTER=$health, CHANGE=$damageToHealth")
|
||||
sender ! Vitality.DamageResolution(turret, cause)
|
||||
FacilityTurretControl.HandleDamageResolution(turret, cause, damageToHealth)
|
||||
if(damageToHealth > 0) {
|
||||
val name = turret.Actor.toString
|
||||
val slashPoint = name.lastIndexOf("/")
|
||||
org.log4s.getLogger("DamageResolution").info(s"${name.substring(slashPoint + 1, name.length - 1)}: BEFORE=$originalHealth, AFTER=$health, CHANGE=$damageToHealth")
|
||||
}
|
||||
}
|
||||
|
||||
case JammableUnit.Jammered(cause) =>
|
||||
TryJammerWithProjectile(turret, cause)
|
||||
|
||||
case JammableUnit.ClearJammeredSound() =>
|
||||
CancelJammeredSound(turret)
|
||||
|
||||
case JammableUnit.ClearJammeredStatus() =>
|
||||
StopJammeredStatus(turret)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def TryJammerWithProjectile(target : FacilityTurret, cause : ResolvedProjectile) : Unit = {
|
||||
val radius = cause.projectile.profile.DamageRadius
|
||||
JammingUnit.FindJammerDuration(cause.projectile.profile, target) match {
|
||||
case Some(dur) if Vector3.DistanceSquared(cause.hit_pos, cause.target.Position) < radius * radius =>
|
||||
//jammered sound
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 54, 1))
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, JammableUnit.ClearJammeredSound())
|
||||
//jammered status
|
||||
StartJammeredStatus(target, dur)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def StartJammeredStatus(target : PlanetSideServerObject with MountedWeapons, dur : Int) : Unit = {
|
||||
jammeredStatusTimer.cancel
|
||||
FacilityTurretControl.JammeredStatus(target, 1)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredStatusTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, JammableUnit.ClearJammeredStatus())
|
||||
}
|
||||
|
||||
def StopJammeredStatus(target : PlanetSideServerObject with MountedWeapons) : Boolean = {
|
||||
FacilityTurretControl.JammeredStatus(target, 0)
|
||||
jammeredStatusTimer.cancel
|
||||
}
|
||||
|
||||
def CancelJammeredSound(target : PlanetSideServerObject) : Unit = {
|
||||
jammeredSoundTimer.cancel
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 54, 0))
|
||||
}
|
||||
}
|
||||
|
||||
object FacilityTurretControl {
|
||||
def HandleDamageResolution(target : FacilityTurret, cause : ResolvedProjectile, damage : Int) : Unit = {
|
||||
val zone = target.Zone
|
||||
val targetGUID = target.GUID
|
||||
val playerGUID = target.Zone.LivePlayers.find { p => cause.projectile.owner.Name.equals(p.Name) } match {
|
||||
case Some(player) => player.GUID
|
||||
case _ => targetGUID
|
||||
}
|
||||
val continentId = zone.Id
|
||||
if(target.Health > 1) {
|
||||
//alert occupants to damage source
|
||||
if(damage > 0) {
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause.target, cause.projectile.owner, cause.hit_pos)
|
||||
//alert occupants to damage source
|
||||
HandleDamageAwareness(target, playerGUID, cause)
|
||||
}
|
||||
if(cause.projectile.profile.JammerProjectile) {
|
||||
target.Actor ! JammableUnit.Jammered(cause)
|
||||
}
|
||||
}
|
||||
else {
|
||||
//alert to vehicle death (hence, occupants' deaths)
|
||||
HandleDestructionAwareness(target, playerGUID, cause)
|
||||
}
|
||||
zone.VehicleEvents ! VehicleServiceMessage(continentId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.Health))
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleDamageAwareness(target : FacilityTurret, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
val zone = target.Zone
|
||||
val zoneId = zone.Id
|
||||
//alert occupants to damage source
|
||||
target.Seats.values.filter(seat => {
|
||||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.HitHint(attribution, tplayer.GUID))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleDestructionAwareness(target : FacilityTurret, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
target.Actor ! JammableUnit.ClearJammeredSound()
|
||||
target.Actor ! JammableUnit.ClearJammeredStatus()
|
||||
val zone = target.Zone
|
||||
val zoneId = zone.Id
|
||||
target.Seats.values.filter(seat => {
|
||||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
})
|
||||
//turret wreckage has no weapons
|
||||
// target.Weapons.values
|
||||
// .filter {
|
||||
// _.Equipment.nonEmpty
|
||||
// }
|
||||
// .foreach(slot => {
|
||||
// val wep = slot.Equipment.get
|
||||
// zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
|
||||
// })
|
||||
// zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.Destroy(targetGUID, playerGUID, playerGUID, player.Position))
|
||||
target.Health = 1 //TODO turret "death" at 0, as is proper
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 0, target.Health)) //TODO not necessary
|
||||
if(target.Upgrade != TurretUpgrade.None) {
|
||||
zone.VehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), zone))
|
||||
zone.VehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, zone, TurretUpgrade.None))
|
||||
}
|
||||
}
|
||||
|
||||
def JammeredStatus(target : PlanetSideServerObject with MountedWeapons, statusCode : Int) : Unit = {
|
||||
val zone = target.Zone
|
||||
val zoneId = zone.Id
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 27, statusCode))
|
||||
target.Weapons.values
|
||||
.map { _.Equipment }
|
||||
.collect {
|
||||
case Some(item : Tool) =>
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, item.GUID, 27, statusCode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ package net.psforever.objects.vehicles
|
|||
import akka.actor.{Actor, ActorRef, Cancellable}
|
||||
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions, Tool, Vehicle}
|
||||
import net.psforever.objects.ballistics.{ResolvedProjectile, VehicleSource}
|
||||
import net.psforever.objects.equipment.JammingUnit
|
||||
import net.psforever.objects.equipment.{JammableUnit, JammingUnit}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.deploy.{Deployment, DeploymentBehavior}
|
||||
|
|
@ -90,7 +91,7 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
val shields = vehicle.Shields
|
||||
val damageToHealth = originalHealth - health
|
||||
val damageToShields = originalShields - shields
|
||||
VehicleControl.HandleVehicleDamageResolution(vehicle, cause, damageToHealth + damageToShields)
|
||||
VehicleControl.HandleDamageResolution(vehicle, cause, damageToHealth + damageToShields)
|
||||
if(damageToHealth > 0 || damageToShields > 0) {
|
||||
val name = vehicle.Actor.toString
|
||||
val slashPoint = name.lastIndexOf("/")
|
||||
|
|
@ -115,13 +116,13 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
}
|
||||
sender ! FactionAffinity.AssertFactionAffinity(vehicle, faction)
|
||||
|
||||
case VehicleControl.Jammered(cause) =>
|
||||
TryJammerVehicleWithProjectile(vehicle, cause)
|
||||
case JammableUnit.Jammered(cause) =>
|
||||
TryJammerWithProjectile(vehicle, cause)
|
||||
|
||||
case VehicleControl.ClearJammeredSound() =>
|
||||
case JammableUnit.ClearJammeredSound() =>
|
||||
CancelJammeredSound(vehicle)
|
||||
|
||||
case VehicleControl.ClearJammeredStatus() =>
|
||||
case JammableUnit.ClearJammeredStatus() =>
|
||||
StopJammeredStatus(vehicle)
|
||||
|
||||
case Vehicle.PrepareForDeletion =>
|
||||
|
|
@ -133,10 +134,10 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
def Disabled : Receive = checkBehavior
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case VehicleControl.ClearJammeredSound() =>
|
||||
case JammableUnit.ClearJammeredSound() =>
|
||||
CancelJammeredSound(vehicle)
|
||||
|
||||
case VehicleControl.ClearJammeredStatus() =>
|
||||
case JammableUnit.ClearJammeredStatus() =>
|
||||
StopJammeredStatus(vehicle)
|
||||
|
||||
case Vehicle.Reactivate =>
|
||||
|
|
@ -145,49 +146,40 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
case _ => ;
|
||||
}
|
||||
|
||||
def TryJammerVehicleWithProjectile(target : Vehicle, cause : ResolvedProjectile) : Unit = {
|
||||
def TryJammerWithProjectile(target : Vehicle, cause : ResolvedProjectile) : Unit = {
|
||||
val radius = cause.projectile.profile.DamageRadius
|
||||
JammingUnit.FindJammerDuration(cause.projectile.profile, target) match {
|
||||
case Some(dur) if Vector3.DistanceSquared(cause.hit_pos, cause.target.Position) < radius * radius =>
|
||||
//jammered sound
|
||||
jammeredSoundTimer.cancel
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 54, 1))
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, VehicleControl.ClearJammeredSound())
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, JammableUnit.ClearJammeredSound())
|
||||
//jammered status
|
||||
StartJammeredStatus(target, dur)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def StartJammeredStatus(target : Vehicle, dur : Int) : Boolean = {
|
||||
if(jammeredStatusTimer.isCancelled) {
|
||||
VehicleControl.JammeredStatus(target, 1)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredStatusTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, VehicleControl.ClearJammeredStatus())
|
||||
true
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
def StartJammeredStatus(target : PlanetSideServerObject with MountedWeapons, dur : Int) : Unit = {
|
||||
jammeredStatusTimer.cancel
|
||||
VehicleControl.JammeredStatus(target, 1)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredStatusTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, JammableUnit.ClearJammeredStatus())
|
||||
}
|
||||
|
||||
def StopJammeredStatus(target : Vehicle) : Boolean = {
|
||||
def StopJammeredStatus(target : PlanetSideServerObject with MountedWeapons) : Boolean = {
|
||||
VehicleControl.JammeredStatus(target, 0)
|
||||
jammeredStatusTimer.cancel
|
||||
}
|
||||
|
||||
def CancelJammeredSound(target : Vehicle) : Unit = {
|
||||
def CancelJammeredSound(target : PlanetSideServerObject) : Unit = {
|
||||
jammeredSoundTimer.cancel
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 54, 0))
|
||||
}
|
||||
}
|
||||
|
||||
object VehicleControl {
|
||||
private final case class Jammered(cause : ResolvedProjectile)
|
||||
|
||||
private final case class ClearJammeredSound()
|
||||
|
||||
private final case class ClearJammeredStatus()
|
||||
import net.psforever.objects.vital.{DamageFromProjectile, VehicleShieldCharge, VitalsActivity}
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -211,29 +203,30 @@ object VehicleControl {
|
|||
* na
|
||||
* @param target na
|
||||
*/
|
||||
def HandleVehicleDamageResolution(target : Vehicle, cause : ResolvedProjectile, damage : Int) : Unit = {
|
||||
def HandleDamageResolution(target : Vehicle, cause : ResolvedProjectile, damage : Int) : Unit = {
|
||||
val zone = target.Zone
|
||||
val targetGUID = target.GUID
|
||||
val playerGUID = target.Zone.LivePlayers.find { p => cause.projectile.owner.Name.equals(p.Name) } match {
|
||||
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) {
|
||||
target.Zone.Activity ! Zone.HotSpot.Activity(cause.target, cause.projectile.owner, cause.hit_pos)
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause.target, cause.projectile.owner, cause.hit_pos)
|
||||
//alert occupants to damage source
|
||||
HandleVehicleDamageAwareness(target, playerGUID, cause)
|
||||
HandleDamageAwareness(target, playerGUID, cause)
|
||||
}
|
||||
if(cause.projectile.profile.JammerProjectile) {
|
||||
target.Actor ! VehicleControl.Jammered(cause)
|
||||
target.Actor ! JammableUnit.Jammered(cause)
|
||||
}
|
||||
}
|
||||
else {
|
||||
//alert to vehicle death (hence, occupants' deaths)
|
||||
HandleVehicleDestructionAwareness(target, playerGUID, cause)
|
||||
HandleDestructionAwareness(target, playerGUID, cause)
|
||||
}
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.Health))
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(s"${target.Actor}", VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 68, target.Shields))
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.Health))
|
||||
zone.VehicleEvents ! VehicleServiceMessage(s"${target.Actor}", VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 68, target.Shields))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -242,13 +235,14 @@ object VehicleControl {
|
|||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleVehicleDamageAwareness(target : Vehicle, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
def HandleDamageAwareness(target : Vehicle, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
val zone = target.Zone
|
||||
//alert occupants to damage source
|
||||
target.Seats.values.filter(seat => {
|
||||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.HitHint(attribution, tplayer.GUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.HitHint(attribution, tplayer.GUID))
|
||||
})
|
||||
//alert cargo occupants to damage source
|
||||
target.CargoHolds.values.foreach(hold => {
|
||||
|
|
@ -257,7 +251,7 @@ object VehicleControl {
|
|||
cargo.Health = 0
|
||||
cargo.Shields = 0
|
||||
cargo.History(lastShot)
|
||||
HandleVehicleDamageAwareness(cargo, attribution, lastShot)
|
||||
HandleDamageAwareness(cargo, attribution, lastShot)
|
||||
case None => ;
|
||||
}
|
||||
})
|
||||
|
|
@ -269,16 +263,19 @@ object VehicleControl {
|
|||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleVehicleDestructionAwareness(target : Vehicle, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
val continentId = target.Zone.Id
|
||||
def HandleDestructionAwareness(target : Vehicle, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
target.Actor ! JammableUnit.ClearJammeredSound()
|
||||
target.Actor ! JammableUnit.ClearJammeredStatus()
|
||||
val zone = target.Zone
|
||||
val continentId = zone.Id
|
||||
//alert to vehicle death (hence, occupants' deaths)
|
||||
target.Seats.values.filter(seat => {
|
||||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
})
|
||||
//vehicle wreckage has no weapons
|
||||
target.Weapons.values
|
||||
|
|
@ -287,7 +284,7 @@ object VehicleControl {
|
|||
}
|
||||
.foreach(slot => {
|
||||
val wep = slot.Equipment.get
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
|
||||
})
|
||||
target.CargoHolds.values.foreach(hold => {
|
||||
hold.Occupant match {
|
||||
|
|
@ -296,7 +293,7 @@ object VehicleControl {
|
|||
cargo.Shields = 0
|
||||
cargo.Position += Vector3.z(1)
|
||||
cargo.History(lastShot) //necessary to kill cargo vehicle occupants //TODO: collision damage
|
||||
HandleVehicleDestructionAwareness(cargo, attribution, lastShot) //might cause redundant packets
|
||||
HandleDestructionAwareness(cargo, attribution, lastShot) //might cause redundant packets
|
||||
case None => ;
|
||||
}
|
||||
})
|
||||
|
|
@ -305,22 +302,24 @@ object VehicleControl {
|
|||
target.Actor ! Deployment.TryDeploymentChange(DriveState.Undeploying)
|
||||
case GlobalDefinitions.router =>
|
||||
target.Actor ! Deployment.TryDeploymentChange(DriveState.Undeploying)
|
||||
VehicleService.BeforeUnloadVehicle(target, target.Zone)
|
||||
target.Zone.LocalEvents ! LocalServiceMessage(target.Zone.Id, LocalAction.ToggleTeleportSystem(PlanetSideGUID(0), target, None))
|
||||
VehicleService.BeforeUnloadVehicle(target, zone)
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.Id, LocalAction.ToggleTeleportSystem(PlanetSideGUID(0), target, None))
|
||||
case _ => ;
|
||||
}
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(target), target.Zone))
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.AddTask(target, target.Zone, Some(1 minute)))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.Destroy(target.GUID, attribution, attribution, target.Position))
|
||||
zone.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(target), zone))
|
||||
zone.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.AddTask(target, zone, Some(1 minute)))
|
||||
}
|
||||
|
||||
def JammeredStatus(target : Vehicle, statusCode : Int) : Unit = {
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 27, statusCode))
|
||||
def JammeredStatus(target : PlanetSideServerObject with MountedWeapons, statusCode : Int) : Unit = {
|
||||
val zone = target.Zone
|
||||
val zoneId = zone.Id
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 27, statusCode))
|
||||
target.Weapons.values
|
||||
.map { _.Equipment }
|
||||
.collect {
|
||||
case Some(item : Tool) =>
|
||||
target.Zone.VehicleEvents ! VehicleServiceMessage(target.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, item.GUID, 27, statusCode))
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, item.GUID, 27, statusCode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ import scodec.codecs._
|
|||
* `27 - PA_JAMMED - plays jammed buzzing sound`<br>
|
||||
* `28 - PA_IMPLANT_ACTIVE - Plays implant sounds. Valid values seem to be up to 20.`<br>
|
||||
* `29 - PA_VAPORIZED - Visible ?! That's not the cloaked effect, Maybe for spectator mode ?. Value is 0 to visible, 1 to invisible.`<br>
|
||||
* `31 - Looking for Squad info (marquee and ui):<br>
|
||||
* `31 - Looking for Squad info (marquee and ui):`<br>
|
||||
* ` - 0 is LFS`<br>
|
||||
* ` - 1 is LFSM (Looking for Squad Members)`<br>
|
||||
* ` - n is the supplemental squad identifier number; same as "LFS;" for the leader, sets "LFSM" after the first manual flagging`<br>
|
||||
|
|
|
|||
|
|
@ -1143,9 +1143,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
AnnounceDestroyDeployable(target, None)
|
||||
}
|
||||
|
||||
case Vitality.DamageResolution(target : FacilityTurret, _) =>
|
||||
HandleFacilityTurretDamageResolution(target)
|
||||
|
||||
case Vitality.DamageResolution(target : PlanetSideGameObject, _) =>
|
||||
log.warn(s"Vital target ${target.Definition.Name} damage resolution not supported using this method")
|
||||
|
||||
|
|
@ -1335,16 +1332,18 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(PlanetsideAttributeMessage(player.GUID, 54, 1))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player.GUID, 54, 1))
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer.cancel
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, ClearJammeredSound())
|
||||
//jammered status
|
||||
skipStaminaRegenForTurns = 5
|
||||
jammeredEquipment = player.Holsters()
|
||||
jammeredEquipment = (jammeredEquipment ++ player.Holsters()
|
||||
.map { _.Equipment }
|
||||
.collect {
|
||||
case Some(item) if item.Size != EquipmentSize.Melee =>
|
||||
sendResponse(PlanetsideAttributeMessage(item.GUID, 24, 1))
|
||||
sendResponse(PlanetsideAttributeMessage(item.GUID, 27, 1))
|
||||
item.GUID
|
||||
}
|
||||
}).distinct
|
||||
jammeredStatusTimer.cancel
|
||||
jammeredStatusTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, ClearJammeredStatus())
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -2995,48 +2994,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
continent.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.PlanetsideAttribute(guid, 0, health))
|
||||
}
|
||||
|
||||
def HandleFacilityTurretDamageResolution(target : FacilityTurret) : Unit = {
|
||||
val targetGUID = target.GUID
|
||||
val playerGUID = player.GUID
|
||||
val continentId = continent.Id
|
||||
val players = target.Seats.values.filter(seat => {
|
||||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
})
|
||||
if(target.Health > 1) { //TODO turret "death" at 0, as is proper
|
||||
//alert occupants to damage source
|
||||
players.foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
continent.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.HitHint(playerGUID, tplayer.GUID))
|
||||
})
|
||||
}
|
||||
else {
|
||||
//alert to vehicle death (hence, occupants' deaths)
|
||||
players.foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
continent.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
})
|
||||
//turret wreckage has no weapons
|
||||
// target.Weapons.values
|
||||
// .filter {
|
||||
// _.Equipment.nonEmpty
|
||||
// }
|
||||
// .foreach(slot => {
|
||||
// val wep = slot.Equipment.get
|
||||
// continent.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
|
||||
// })
|
||||
// continent.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.Destroy(targetGUID, playerGUID, playerGUID, player.Position))
|
||||
target.Health = 1
|
||||
continent.VehicleEvents ! VehicleServiceMessage(continentId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.MaxHealth)) //TODO not necessary
|
||||
if(target.Upgrade != TurretUpgrade.None) {
|
||||
continent.VehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), continent))
|
||||
continent.VehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, continent, TurretUpgrade.None))
|
||||
}
|
||||
}
|
||||
continent.VehicleEvents ! VehicleServiceMessage(continentId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, target.Health))
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param tplayer na
|
||||
|
|
@ -4691,7 +4648,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
case msg @ UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType) =>
|
||||
log.info("UseItem: " + msg)
|
||||
//log.info("UseItem: " + msg)
|
||||
// TODO: Not all fields in the response are identical to source in real packet logs (but seems to be ok)
|
||||
// TODO: Not all incoming UseItemMessage's respond with another UseItemMessage (i.e. doors only send out GenericObjectStateMsg)
|
||||
continent.GUID(object_guid) match {
|
||||
|
|
@ -7844,10 +7801,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* This is not a complete list but, for the purpose of enforcement, some pointers will be documented here.
|
||||
*/
|
||||
def PlayerActionsToCancel() : Unit = {
|
||||
if(!jammeredSoundTimer.isCancelled) {
|
||||
CancelJammeredSound()
|
||||
}
|
||||
jammeredStatusTimer.cancel
|
||||
CancelJammeredSound()
|
||||
CancelJammeredStatus()
|
||||
progressBarUpdate.cancel
|
||||
progressBarValue = None
|
||||
lastTerminalOrderFulfillment = true
|
||||
|
|
@ -8571,14 +8526,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
//damage is synchronized on the target player's `WSA` (results distributed from there)
|
||||
continent.AvatarEvents ! AvatarServiceMessage(obj.Name, AvatarAction.Damage(player.GUID, obj, func))
|
||||
case obj : Vehicle =>
|
||||
//damage is synchronized on the vehicle actor (results returned to and distributed from this `WSA`)
|
||||
//damage is synchronized on the vehicle actor
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
case obj : FacilityTurret =>
|
||||
//damage is synchronized on the turret actor
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
case obj : Deployable =>
|
||||
//damage is synchronized on `LSA` (results returned to and distributed from this `WSA`)
|
||||
continent.LocalEvents ! Vitality.DamageOn(obj, func)
|
||||
case obj : FacilityTurret =>
|
||||
//damage is synchronized on the turret actor (results returned to and distributed from this `WSA`)
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -10294,10 +10249,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
def CancelJammeredStatus() : Unit = {
|
||||
if(!jammeredSoundTimer.isCancelled) {
|
||||
CancelJammeredSound()
|
||||
}
|
||||
jammeredEquipment.foreach { id => sendResponse(PlanetsideAttributeMessage(id, 24, 0)) }
|
||||
jammeredStatusTimer.cancel
|
||||
jammeredEquipment.foreach { id => sendResponse(PlanetsideAttributeMessage(id, 27, 0)) }
|
||||
jammeredEquipment = Nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue