mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
adjusted CommonFieldData to support jammering effect flag; fixed tests; made jammering sound and status contingent on state, but made cancelling sound and status always call up
This commit is contained in:
parent
879be93863
commit
6c76997675
|
|
@ -61,31 +61,35 @@ class SensorDeployableControl(sensor : SensorDeployable) extends Actor
|
|||
}
|
||||
|
||||
override def StartJammeredSound(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : PlanetSideServerObject =>
|
||||
case obj : PlanetSideServerObject if !jammedSound =>
|
||||
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 =>
|
||||
case obj : PlanetSideServerObject with JammableUnit if !obj.Jammed =>
|
||||
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 CancelJammeredSound(target : Any) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject if jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 0))
|
||||
case _ => ;
|
||||
}
|
||||
super.CancelJammeredSound(target)
|
||||
}
|
||||
|
||||
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 _ => ;
|
||||
override def CancelJammeredStatus(target : Any) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject with JammableUnit if obj.Jammed =>
|
||||
sensor.Zone.LocalEvents ! LocalServiceMessage(sensor.Zone.Id, LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, true, 1000))
|
||||
case _ => ;
|
||||
}
|
||||
super.CancelJammeredStatus(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,19 +60,21 @@ class ShieldGeneratorControl(gen : ShieldGeneratorDeployable) extends Actor
|
|||
override def StartJammeredSound(target : Any, dur : Int) : Unit = { }
|
||||
|
||||
override def StartJammeredStatus(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))
|
||||
case obj : PlanetSideServerObject with JammableUnit if !obj.Jammed =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1))
|
||||
super.StartJammeredStatus(obj, dur)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
override def CancelJammeredSound(target : Any) : Unit = { }
|
||||
|
||||
override def CancelJammeredStatus(target : Any) : Unit = target match {
|
||||
case obj : PlanetSideServerObject =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 0))
|
||||
super.CancelJammeredStatus(obj)
|
||||
case _ => ;
|
||||
override def CancelJammeredStatus(target : Any) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject with JammableUnit if obj.Jammed =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0))
|
||||
case _ => ;
|
||||
}
|
||||
super.CancelJammeredStatus(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ import scala.annotation.tailrec
|
|||
* @param toolDef the `ObjectDefinition` that constructs this item and maintains some of its immutable fields
|
||||
*/
|
||||
class Tool(private val toolDef : ToolDefinition) extends Equipment
|
||||
with FireModeSwitch[FireModeDefinition] {
|
||||
with FireModeSwitch[FireModeDefinition]
|
||||
with JammableUnit {
|
||||
/** index of the current fire mode on the `ToolDefinition`'s list of fire modes */
|
||||
private var fireModeIndex : Int = toolDef.DefaultFireModeIndex
|
||||
/** current ammunition slot being used by this fire mode */
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ object AvatarConverter {
|
|||
alt_model_flag,
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
obj.Jammed,
|
||||
None,
|
||||
v5 = None,
|
||||
PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.definition.converter
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.{Player, Tool}
|
||||
import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
|
|
@ -136,17 +136,38 @@ class CharacterSelectConverter extends AvatarConverter {
|
|||
}
|
||||
else {
|
||||
val slot : EquipmentSlot = iter.next
|
||||
if(slot.Equipment.isDefined) {
|
||||
val equip : Equipment = slot.Equipment.get
|
||||
recursiveMakeHolsters(
|
||||
iter,
|
||||
list :+ AvatarConverter.BuildDetailedEquipment(index, equip),
|
||||
index + 1
|
||||
)
|
||||
}
|
||||
else {
|
||||
recursiveMakeHolsters(iter, list, index + 1)
|
||||
slot.Equipment match {
|
||||
case Some(equip : Tool) =>
|
||||
val jammed = equip.Jammed
|
||||
equip.Jammed = false
|
||||
val slot = AvatarConverter.BuildDetailedEquipment(index, equip)
|
||||
equip.Jammed = jammed
|
||||
recursiveMakeHolsters(
|
||||
iter,
|
||||
list :+ slot,
|
||||
index + 1
|
||||
)
|
||||
case Some(equip) =>
|
||||
recursiveMakeHolsters(
|
||||
iter,
|
||||
list :+ AvatarConverter.BuildDetailedEquipment(index, equip),
|
||||
index + 1
|
||||
)
|
||||
case _ =>
|
||||
recursiveMakeHolsters(iter, list, index + 1)
|
||||
}
|
||||
// if(slot.Equipment.isDefined) {
|
||||
//
|
||||
// val equip : Equipment = slot.Equipment.get
|
||||
// recursiveMakeHolsters(
|
||||
// iter,
|
||||
// list :+ AvatarConverter.BuildDetailedEquipment(index, equip),
|
||||
// index + 1
|
||||
// )
|
||||
// }
|
||||
// else {
|
||||
// recursiveMakeHolsters(iter, list, index + 1)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class FieldTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
|
|||
alternate = false,
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
jammered = obj.Jammed,
|
||||
Some(false),
|
||||
None,
|
||||
obj.Owner match {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ShieldGeneratorConverter extends ObjectCreateConverter[ShieldGeneratorDepl
|
|||
alternate = false,
|
||||
v1 = false,
|
||||
v2 = None,
|
||||
v3 = false,
|
||||
jammered = obj.Jammed,
|
||||
None,
|
||||
None,
|
||||
obj.Owner match {
|
||||
|
|
@ -45,7 +45,7 @@ class ShieldGeneratorConverter extends ObjectCreateConverter[ShieldGeneratorDepl
|
|||
alternate = true,
|
||||
v1 = false,
|
||||
v2 = None,
|
||||
v3 = false,
|
||||
jammered = obj.Jammed,
|
||||
None,
|
||||
None,
|
||||
PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.definition.converter
|
|||
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
|
||||
|
|
@ -15,11 +16,14 @@ class SmallDeployableConverter extends ObjectCreateConverter[PlanetSideGameObjec
|
|||
PlacementData(obj.Position, obj.Orientation),
|
||||
CommonFieldData(
|
||||
obj.Faction,
|
||||
false,
|
||||
false,
|
||||
bops = false,
|
||||
alternate = false,
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
jammered = obj match {
|
||||
case o : JammableUnit => o.Jammed
|
||||
case _ => false
|
||||
},
|
||||
Some(false),
|
||||
None,
|
||||
obj.Owner match {
|
||||
|
|
@ -33,4 +37,4 @@ class SmallDeployableConverter extends ObjectCreateConverter[PlanetSideGameObjec
|
|||
|
||||
override def DetailedConstructorData(obj : PlanetSideGameObject with Deployable) : Try[CommonFieldDataWithPlacement] =
|
||||
Failure(new Exception("converter should not be used to generate detailed small deployable data"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class SmallTurretConverter extends ObjectCreateConverter[TurretDeployable]() {
|
|||
alternate = false,
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
jammered = obj.Jammed,
|
||||
Some(true),
|
||||
None,
|
||||
obj.Owner match {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ToolConverter extends ObjectCreateConverter[Tool]() {
|
|||
alternate = false,
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
obj.Jammed,
|
||||
None,
|
||||
None,
|
||||
PlanetSideGUID(0)
|
||||
|
|
@ -45,7 +45,7 @@ class ToolConverter extends ObjectCreateConverter[Tool]() {
|
|||
alternate = false,
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
obj.Jammed,
|
||||
None,
|
||||
None,
|
||||
PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
|
|||
alternate = false,
|
||||
v1 = false,
|
||||
v2 = None,
|
||||
v3 = false,
|
||||
jammered = obj.Jammed,
|
||||
v4 = Some(false),
|
||||
v5 = None,
|
||||
obj.Owner match {
|
||||
|
|
@ -56,7 +56,7 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
|
|||
alternate = true,
|
||||
v1 = false,
|
||||
v2 = None,
|
||||
v3 = false,
|
||||
jammered = obj.Jammed,
|
||||
v4 = Some(false),
|
||||
v5 = None,
|
||||
guid = PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.terminals
|
||||
package net.psforever.objects.equipment
|
||||
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.ce.DeployableCategory
|
||||
|
|
@ -5,7 +5,6 @@ import akka.actor.{Actor, Cancellable}
|
|||
import net.psforever.objects.{DefaultCancellable, PlanetSideGameObject, Tool}
|
||||
import net.psforever.objects.ballistics.ResolvedProjectile
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.terminals.TargetValidation
|
||||
import net.psforever.objects.vehicles.MountedWeapons
|
||||
import net.psforever.objects.zones.ZoneAware
|
||||
import net.psforever.types.Vector3
|
||||
|
|
@ -15,7 +14,12 @@ import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
|||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* A property conferred to game objects that can be affected by an electromagnetic pulse.
|
||||
* Being "jammered" is a status that causes weakness due to temporary equipment disabling or the elimination of certain objects.
|
||||
*/
|
||||
trait JammableUnit {
|
||||
/** being jammed (jammered) is an on/off state */
|
||||
private var jammed : Boolean = false
|
||||
|
||||
def Jammed : Boolean = jammed
|
||||
|
|
@ -27,16 +31,34 @@ trait JammableUnit {
|
|||
}
|
||||
|
||||
object JammableUnit {
|
||||
/**
|
||||
* A message for generic jammering.
|
||||
* Currently, unused.
|
||||
*/
|
||||
final case class Jammer()
|
||||
|
||||
/**
|
||||
* A message for jammering due to a projectile.
|
||||
* @param cause information pertaining to the projectile
|
||||
*/
|
||||
final case class Jammered(cause : ResolvedProjectile)
|
||||
|
||||
/**
|
||||
* Stop the auditory aspect of being jammered.
|
||||
*/
|
||||
final case class ClearJammeredSound()
|
||||
|
||||
/**
|
||||
* Stop the status effects of being jammered.
|
||||
*/
|
||||
final case class ClearJammeredStatus()
|
||||
}
|
||||
|
||||
/**
|
||||
* A property conferred onto game objects that can induce the effects of an electromagnetic pulse.
|
||||
* @see `TargetValidation`
|
||||
* @see `EffectTarget`
|
||||
*/
|
||||
trait JammingUnit {
|
||||
/** a list of qualifying conditional tests for determining if an object is to be affected by the jammered status;
|
||||
* if qualifying, that object will be inflicted with a number of milliseconds of the jammered status */
|
||||
private val jammedEffectDuration : mutable.ListBuffer[(TargetValidation, Int)] = new mutable.ListBuffer()
|
||||
|
||||
def HasJammedEffectDuration : Boolean = jammedEffectDuration.isEmpty
|
||||
|
|
@ -45,6 +67,15 @@ trait JammingUnit {
|
|||
}
|
||||
|
||||
object JammingUnit {
|
||||
/**
|
||||
* Determine whether an object that can be jammered is to be jammered by this source,
|
||||
* and for how long.
|
||||
* If the object succeeds for multiple qualification tests,
|
||||
* prioritize the lengthiest duration.
|
||||
* @param jammer the source of the "jammered" status
|
||||
* @param target the object to be determined if affected by the source's jammering
|
||||
* @return the duration to be jammered, if any, in milliseconds
|
||||
*/
|
||||
def FindJammerDuration(jammer : JammingUnit, target : PlanetSideGameObject) : Option[Int] = {
|
||||
jammer.JammedEffectDuration
|
||||
.collect { case (TargetValidation(_, test), duration) if test(target) => duration }
|
||||
|
|
@ -53,18 +84,45 @@ object JammingUnit {
|
|||
.headOption
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a group of objects that can be jammered is to be jammered by this source,
|
||||
* and for how long.
|
||||
* If the object succeeds for multiple qualification tests,
|
||||
* prioritize the lengthiest duration.
|
||||
* @param jammer the source of the "jammered" status
|
||||
* @param targets the objects to be determined if affected by the source's jammering
|
||||
* @return the indexed durations to be jammered, if any, in milliseconds
|
||||
*/
|
||||
def FindJammerDuration(jammer : JammingUnit, targets : Seq[PlanetSideGameObject]) : Seq[Option[Int]] = {
|
||||
targets.map { target => FindJammerDuration(jammer, target) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An `Actor` control object mix-in that manages common responses to the "jammerable" status.
|
||||
* Two aspects to jammering are supported -
|
||||
* a telling buzzing sound that follows the affected target
|
||||
* and actual effects upon the target's actions -
|
||||
* and are controlled independently.
|
||||
* The primary purpose of this behavior is to control timers that toggle the states of these two aspects.
|
||||
*/
|
||||
trait JammableBehavior {
|
||||
_ : Actor =>
|
||||
this : Actor =>
|
||||
/** flag for jammed sound */
|
||||
protected var jammedSound : Boolean = false
|
||||
/** the sound timer */
|
||||
protected var jammeredSoundTimer : Cancellable = DefaultCancellable.obj
|
||||
/** the effect timer */
|
||||
protected var jammeredStatusTimer : Cancellable = DefaultCancellable.obj
|
||||
|
||||
/** `ZoneAware` is used for callback to the event systems */
|
||||
def JammableObject : PlanetSideServerObject with JammableUnit with ZoneAware
|
||||
|
||||
/**
|
||||
* If the target can be validated against, affect it with the jammered status.
|
||||
* @param target the objects to be determined if affected by the source's jammering
|
||||
* @param cause the source of the "jammered" status
|
||||
*/
|
||||
def TryJammerEffectActivate(target : Any, cause : ResolvedProjectile) : Unit = target match {
|
||||
case obj : PlanetSideServerObject =>
|
||||
val radius = cause.projectile.profile.DamageRadius
|
||||
|
|
@ -77,12 +135,30 @@ trait JammableBehavior {
|
|||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a distinctive buzzing sound effect.
|
||||
* Due to considerations of the object that is the target, this is left to be implemented by a subclass.
|
||||
* We merely start the timer.
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds;
|
||||
* by default, 30000
|
||||
*/
|
||||
def StartJammeredSound(target : Any, dur : Int = 30000) : Unit = {
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer.cancel
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, JammableUnit.ClearJammeredSound())
|
||||
if(!jammedSound) {
|
||||
jammedSound = true
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer.cancel
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(30 seconds, self, JammableUnit.ClearJammeredSound())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the effects of the jammered status.
|
||||
* Due to considerations of the object that is the target, this is left to be implemented by a subclass.
|
||||
* We merely stop the timer.
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds
|
||||
*/
|
||||
def StartJammeredStatus(target : Any, dur : Int) : Unit = {
|
||||
JammableObject.Jammed = true
|
||||
jammeredStatusTimer.cancel
|
||||
|
|
@ -90,10 +166,23 @@ trait JammableBehavior {
|
|||
jammeredStatusTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, JammableUnit.ClearJammeredStatus())
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate a distinctive buzzing sound effect.
|
||||
* Due to considerations of the object that is the target, this is left to be implemented by a subclass.
|
||||
* We merely stop the timer.
|
||||
* @param target an object that can be affected by the jammered status
|
||||
*/
|
||||
def CancelJammeredSound(target : Any) : Unit = {
|
||||
jammedSound = false
|
||||
jammeredSoundTimer.cancel
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the effects of the jammered status.
|
||||
* Due to considerations of the object that is the target, this is left to be implemented by a subclass.
|
||||
* We merely stop the timer.
|
||||
* @param target an object that can be affected by the jammered status
|
||||
*/
|
||||
def CancelJammeredStatus(target : Any) : Unit = {
|
||||
JammableObject.Jammed = false
|
||||
jammeredStatusTimer.cancel
|
||||
|
|
@ -111,47 +200,71 @@ trait JammableBehavior {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A common mix-in variation to manage common responses to the "jammerable" status for game objects with mounted weapons.
|
||||
* @see `MountedWeapons`
|
||||
* @see `Service`
|
||||
* @see `VehicleAction`
|
||||
* @see `VehicleService`
|
||||
* @see `VehicleServiceMessage`
|
||||
* @see `Zone.VehicleEvents`
|
||||
*/
|
||||
trait JammableMountedWeapons extends JammableBehavior {
|
||||
_ : Actor =>
|
||||
|
||||
override def StartJammeredSound(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 1))
|
||||
super.StartJammeredSound(obj, dur)
|
||||
case _ => ;
|
||||
override def StartJammeredSound(target : Any, dur : Int) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons with JammableUnit if !jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1))
|
||||
super.StartJammeredSound(target, dur)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
override def StartJammeredStatus(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons =>
|
||||
JammableMountedWeapons.JammeredStatus(obj, 1)
|
||||
super.StartJammeredStatus(obj, dur)
|
||||
case _ => ;
|
||||
override def StartJammeredStatus(target : Any, dur : Int) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons with JammableUnit if !obj.Jammed =>
|
||||
JammableMountedWeapons.JammeredStatus(obj, 1)
|
||||
super.StartJammeredStatus(target, 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 CancelJammeredSound(target : Any) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject if jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(obj.Zone.Id, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0))
|
||||
case _ => ;
|
||||
}
|
||||
super.CancelJammeredSound(target)
|
||||
}
|
||||
|
||||
override def CancelJammeredStatus(target : Any) : Unit = target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons =>
|
||||
JammableMountedWeapons.JammeredStatus(obj, 0)
|
||||
super.CancelJammeredStatus(obj)
|
||||
case _ => ;
|
||||
override def CancelJammeredStatus(target : Any) : Unit = {
|
||||
target match {
|
||||
case obj : PlanetSideServerObject with MountedWeapons with JammableUnit if obj.Jammed =>
|
||||
JammableMountedWeapons.JammeredStatus(obj, 0)
|
||||
case _ => ;
|
||||
}
|
||||
super.CancelJammeredStatus(target)
|
||||
}
|
||||
}
|
||||
|
||||
object JammableMountedWeapons {
|
||||
/**
|
||||
* Retrieve all of the weapons on a `MountedWeapons` target object and apply a jammered status effect to each.
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param statusCode the jammered status condition;
|
||||
* 0 for deactivation;
|
||||
* 1 for activation
|
||||
*/
|
||||
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) =>
|
||||
item.Jammed = statusCode==1
|
||||
zone.VehicleEvents ! VehicleServiceMessage(zoneId, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, item.GUID, 27, statusCode))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.terminals
|
|||
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.equipment.EffectTarget
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
}
|
||||
sender ! FactionAffinity.AssertFactionAffinity(vehicle, faction)
|
||||
|
||||
case Vehicle.PrepareForDeletion =>
|
||||
case Vehicle.PrepareForDeletion() =>
|
||||
CancelJammeredSound(vehicle)
|
||||
CancelJammeredStatus(vehicle)
|
||||
context.become(Disabled)
|
||||
|
|
@ -126,10 +126,10 @@ class VehicleControl(vehicle : Vehicle) extends Actor
|
|||
def Disabled : Receive = checkBehavior
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case Vehicle.Reactivate =>
|
||||
case Vehicle.Reactivate() =>
|
||||
context.become(Enabled)
|
||||
|
||||
case _ => ;
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
|
|||
}
|
||||
else if(data.faction == PlanetSideEmpire.NEUTRAL) {
|
||||
Attempt.successful(
|
||||
CommonFieldData(faction, data.bops, data.alternate, data.v1, data.v2, data.v3, None, data.v5, PlanetSideGUID(0)) ::
|
||||
CommonFieldData(faction, data.bops, data.alternate, data.v1, data.v2, data.jammered, None, data.v5, PlanetSideGUID(0)) ::
|
||||
name :: suit :: u5 :: sex :: head :: v1 :: u6 :: u7 :: u8 :: u9 :: uA :: HNil
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ import scodec.{Attempt, Codec, Err}
|
|||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
final case class CommonFieldDataExtra(unk1 : Int, unk2 : Boolean) extends StreamBitSize {
|
||||
final case class CommonFieldDataExtra(unk1 : Option[Int], unk2 : Boolean) extends StreamBitSize {
|
||||
override def bitsize : Long = 17L
|
||||
}
|
||||
|
||||
object CommonFieldDataExtra {
|
||||
implicit val codec : Codec[CommonFieldDataExtra] = (
|
||||
("unk1" | uint16L) ::
|
||||
def codec(unk1 : Boolean) : Codec[CommonFieldDataExtra] = (
|
||||
("unk1" | conditional(unk1, uint16L)) :: //not sure what flags this field
|
||||
("unk2" | bool)
|
||||
).as[CommonFieldDataExtra]
|
||||
}
|
||||
|
|
@ -28,10 +28,9 @@ object CommonFieldDataExtra {
|
|||
* when set on a tool, that tool will be rendered nonfunctional instead (though it can still be equipped)
|
||||
* @param v1 na
|
||||
* @param v2 na;
|
||||
* optional data whose reading is triggered in unknown conditions;
|
||||
* flag a weapon as "jammered"
|
||||
* @param v3 na;
|
||||
* for weapons, works like `alternate`
|
||||
* optional data whose reading is triggered in unknown conditions
|
||||
* @param jammered flag as "jammered;"
|
||||
* set on most game objects, that object will produce the characteristic jammered buzz
|
||||
* @param v4 na;
|
||||
* a field used by a second encoding format for this data
|
||||
* @param v5 na;
|
||||
|
|
@ -43,7 +42,7 @@ final case class CommonFieldData(faction : PlanetSideEmpire.Value,
|
|||
alternate : Boolean,
|
||||
v1 : Boolean,
|
||||
v2 : Option[CommonFieldDataExtra],
|
||||
v3 : Boolean,
|
||||
jammered : Boolean,
|
||||
v4 : Option[Boolean],
|
||||
v5 : Option[Int],
|
||||
guid : PlanetSideGUID
|
||||
|
|
@ -64,7 +63,7 @@ final case class CommonFieldData(faction : PlanetSideEmpire.Value,
|
|||
23L + extraSize + v4Size + v5Size
|
||||
}
|
||||
|
||||
def apply(flag : Boolean) : CommonFieldData = CommonFieldData(faction, bops, alternate, v1, v2, v3, Some(flag), v5, guid)
|
||||
def apply(flag : Boolean) : CommonFieldData = CommonFieldData(faction, bops, alternate, v1, v2, jammered, Some(flag), v5, guid)
|
||||
}
|
||||
|
||||
object CommonFieldData extends Marshallable[CommonFieldData] {
|
||||
|
|
@ -100,8 +99,8 @@ object CommonFieldData extends Marshallable[CommonFieldData] {
|
|||
("bops" | bool) ::
|
||||
("alternate" | bool) ::
|
||||
("v1" | bool) :: //the purpose of this bit changes depending on the previous bit
|
||||
conditional(extra, "v2" | CommonFieldDataExtra.codec) ::
|
||||
("v3" | bool) ::
|
||||
conditional(extra, "v2" | CommonFieldDataExtra.codec(unk1 = false)) ::
|
||||
("jammered" | bool) ::
|
||||
optional(bool, "v5" | uint16L) ::
|
||||
("guid" | PlanetSideGUID.codec)
|
||||
).xmap[CommonFieldData] (
|
||||
|
|
@ -122,8 +121,8 @@ object CommonFieldData extends Marshallable[CommonFieldData] {
|
|||
("bops" | bool) ::
|
||||
("alternate" | bool) ::
|
||||
("v1" | bool) :: //though the code path differs depending on the previous bit, this one gets read one way or another
|
||||
conditional(extra, "v2" | CommonFieldDataExtra.codec) ::
|
||||
("v3" | bool) ::
|
||||
conditional(extra, "v2" | CommonFieldDataExtra.codec(unk1 = false)) ::
|
||||
("jammered" | bool) ::
|
||||
optional(bool, "v5" | uint16L) ::
|
||||
("v4" | bool) ::
|
||||
("guid" | PlanetSideGUID.codec)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ object OneMannedFieldTurretData extends Marshallable[OneMannedFieldTurretData] {
|
|||
OneMannedFieldTurretData(
|
||||
CommonFieldDataWithPlacement(
|
||||
deploy.pos,
|
||||
CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.v3, data.v4, data.v5, player)
|
||||
CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.jammered, data.v4, data.v5, player)
|
||||
),
|
||||
newHealth,
|
||||
newInternals
|
||||
|
|
@ -92,7 +92,7 @@ object OneMannedFieldTurretData extends Marshallable[OneMannedFieldTurretData] {
|
|||
Attempt.successful(
|
||||
CommonFieldDataWithPlacement(
|
||||
pos,
|
||||
CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.v3, data.v4, data.v5, PlanetSideGUID(0))
|
||||
CommonFieldData(data.faction, data.bops, data.alternate, data.v1, data.v2, data.jammered, data.v4, data.v5, PlanetSideGUID(0))
|
||||
) :: data.guid :: false :: newHealth :: 0 :: 0xF :: 0 :: newInternals :: HNil
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class VehicleRemover extends RemoverActor {
|
|||
val vehicle = entry.obj.asInstanceOf[Vehicle]
|
||||
val vehicleGUID = vehicle.GUID
|
||||
val zoneId = entry.zone.Id
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion()
|
||||
//escape being someone else's cargo
|
||||
(vehicle.MountedIn match {
|
||||
case Some(carrierGUID) =>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class AegisShieldGeneratorDataTest extends Specification {
|
|||
basic.data.alternate mustEqual false
|
||||
basic.data.v1 mustEqual true
|
||||
basic.data.v2.isDefined mustEqual false
|
||||
basic.data.v3 mustEqual false
|
||||
basic.data.jammered mustEqual false
|
||||
basic.data.v5.isDefined mustEqual false
|
||||
basic.data.guid mustEqual PlanetSideGUID(2366)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class CharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Reinforced
|
||||
|
|
@ -162,7 +162,7 @@ class CharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Reinforced
|
||||
|
|
@ -231,7 +231,7 @@ class CharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.MAX
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class OneMannedFieldTurretDataTest extends Specification {
|
|||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.contains(false) mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(2502)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class RemoteProjectileDataTest extends Specification {
|
|||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.isEmpty mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -63,7 +63,7 @@ class RemoteProjectileDataTest extends Specification {
|
|||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.isEmpty mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class SmallTurretDataTest extends Specification {
|
|||
deploy.alternate mustEqual true
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.contains(false) mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(7742)
|
||||
|
|
@ -61,7 +61,7 @@ class SmallTurretDataTest extends Specification {
|
|||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.contains(true) mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(8208)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class TRAPDataTest extends Specification {
|
|||
deploy.alternate mustEqual false
|
||||
deploy.v1 mustEqual true
|
||||
deploy.v2.isEmpty mustEqual true
|
||||
deploy.v3 mustEqual false
|
||||
deploy.jammered mustEqual false
|
||||
deploy.v4.contains(true) mustEqual true
|
||||
deploy.v5.isEmpty mustEqual true
|
||||
deploy.guid mustEqual PlanetSideGUID(4748)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual true
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Standard
|
||||
|
|
@ -259,7 +259,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Standard
|
||||
|
|
@ -444,7 +444,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual true
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.MAX
|
||||
|
|
@ -652,7 +652,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual true
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Agile
|
||||
|
|
@ -1104,7 +1104,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
cdata.data.alternate mustEqual false
|
||||
cdata.data.v1 mustEqual true
|
||||
cdata.data.v2.isEmpty mustEqual true
|
||||
cdata.data.v3 mustEqual false
|
||||
cdata.data.jammered mustEqual false
|
||||
cdata.data.v4.isEmpty mustEqual true
|
||||
cdata.data.v5.isEmpty mustEqual true
|
||||
cdata.data.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -1160,7 +1160,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.alternate mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Standard
|
||||
|
|
@ -1310,7 +1310,7 @@ class DetailedCharacterDataTest extends Specification {
|
|||
a.data.alternate mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Standard
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
cdata.alternate mustEqual false
|
||||
cdata.v1 mustEqual true
|
||||
cdata.v2.isEmpty mustEqual true
|
||||
cdata.v3 mustEqual false
|
||||
cdata.jammered mustEqual false
|
||||
cdata.v4.isEmpty mustEqual true
|
||||
cdata.v5.isEmpty mustEqual true
|
||||
cdata.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -71,7 +71,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
cdata.alternate mustEqual false
|
||||
cdata.v1 mustEqual true
|
||||
cdata.v2.isEmpty mustEqual true
|
||||
cdata.v3 mustEqual false
|
||||
cdata.jammered mustEqual false
|
||||
cdata.v4.isEmpty mustEqual true
|
||||
cdata.v5.isEmpty mustEqual true
|
||||
cdata.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -111,7 +111,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
cdata.alternate mustEqual false
|
||||
cdata.v1 mustEqual true
|
||||
cdata.v2.isEmpty mustEqual true
|
||||
cdata.v3 mustEqual false
|
||||
cdata.jammered mustEqual false
|
||||
cdata.v4.isEmpty mustEqual true
|
||||
cdata.v5.contains(564) mustEqual true
|
||||
cdata.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
@ -139,7 +139,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
cdata.alternate mustEqual false
|
||||
cdata.v1 mustEqual false
|
||||
cdata.v2.isEmpty mustEqual true
|
||||
cdata.v3 mustEqual false
|
||||
cdata.jammered mustEqual false
|
||||
cdata.v4.isEmpty mustEqual true
|
||||
cdata.v5.isEmpty mustEqual true
|
||||
cdata.guid mustEqual PlanetSideGUID(0)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class MountedVehiclesTest extends Specification {
|
|||
vdata.data.bops mustEqual false
|
||||
vdata.data.alternate mustEqual false
|
||||
vdata.data.v1 mustEqual false
|
||||
vdata.data.v3 mustEqual false
|
||||
vdata.data.jammered mustEqual false
|
||||
vdata.data.v5.isEmpty mustEqual true
|
||||
vdata.data.guid mustEqual PlanetSideGUID(3776)
|
||||
vdata.health mustEqual 255
|
||||
|
|
@ -57,7 +57,7 @@ class MountedVehiclesTest extends Specification {
|
|||
a.data.bops mustEqual false
|
||||
a.data.v1 mustEqual false
|
||||
a.data.v2.isEmpty mustEqual true
|
||||
a.data.v3 mustEqual false
|
||||
a.data.jammered mustEqual false
|
||||
a.data.v4.isEmpty mustEqual true
|
||||
a.data.v5.isEmpty mustEqual true
|
||||
a.exosuit mustEqual ExoSuitType.Agile
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class NonstandardVehiclesTest extends Specification {
|
|||
basic.data.alternate mustEqual false
|
||||
basic.data.v1 mustEqual true
|
||||
basic.data.v2.isDefined mustEqual false
|
||||
basic.data.v3 mustEqual false
|
||||
basic.data.jammered mustEqual false
|
||||
basic.data.v5.isDefined mustEqual false
|
||||
basic.data.guid mustEqual PlanetSideGUID(0)
|
||||
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ class NormalVehiclesTest extends Specification {
|
|||
vdata.faction mustEqual PlanetSideEmpire.NC
|
||||
vdata.alternate mustEqual false
|
||||
vdata.v1 mustEqual true
|
||||
vdata.v3 mustEqual false
|
||||
vdata.jammered mustEqual false
|
||||
vdata.v5.isEmpty mustEqual true
|
||||
vdata.guid mustEqual PlanetSideGUID(0)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class UtilityVehiclesTest extends Specification {
|
|||
ant.data.faction mustEqual PlanetSideEmpire.VS
|
||||
ant.data.alternate mustEqual false
|
||||
ant.data.v1 mustEqual true
|
||||
ant.data.v3 mustEqual false
|
||||
ant.data.jammered mustEqual false
|
||||
ant.data.v5.isEmpty mustEqual true
|
||||
ant.data.guid mustEqual PlanetSideGUID(0)
|
||||
ant.driveState mustEqual DriveState.Mobile
|
||||
|
|
@ -59,7 +59,7 @@ class UtilityVehiclesTest extends Specification {
|
|||
ams.data.faction mustEqual PlanetSideEmpire.VS
|
||||
ams.data.alternate mustEqual false
|
||||
ams.data.v1 mustEqual false
|
||||
ams.data.v3 mustEqual false
|
||||
ams.data.jammered mustEqual false
|
||||
ams.data.v5.isEmpty mustEqual true
|
||||
ams.data.guid mustEqual PlanetSideGUID(2885)
|
||||
ams.driveState mustEqual DriveState.Deployed
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package objects
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.ballistics.{PlayerSource, Projectile, ProjectileResolution, ResolvedProjectile}
|
||||
|
|
@ -9,9 +10,11 @@ import net.psforever.objects.definition.{SeatDefinition, VehicleDefinition}
|
|||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vital.{VehicleShieldCharge, Vitality}
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable._
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -324,66 +327,82 @@ class VehicleControlStopMountingTest extends ActorTest {
|
|||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = new TestProbe(system).ref //necessary
|
||||
}
|
||||
vehicle.Weapons(2).Equipment.get.GUID = PlanetSideGUID(4)
|
||||
val probe = new TestProbe(system)
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
val reply = probe.receiveOne(Duration.create(200, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
expectNoMsg(Duration.create(200, "ms"))
|
||||
vehicle.Actor.tell(Vehicle.PrepareForDeletion(), probe.ref)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 1), probe.ref)
|
||||
probe.expectNoMsg(Duration.create(200, "ms")) //assertion failed: received unexpected message MountMessages(CanMount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlRestartMountingTest extends ActorTest {
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = new TestProbe(system).ref
|
||||
}
|
||||
vehicle.Weapons(2).Equipment.get.GUID = PlanetSideGUID(4)
|
||||
val probe = new TestProbe(system)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"reactivate and resume handling mount messages" in {
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
probe.receiveOne(Duration.create(200, "ms")) //discard
|
||||
vehicle.Actor.tell(Vehicle.PrepareForDeletion(), probe.ref)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 1), probe.ref)
|
||||
probe.expectNoMsg(Duration.create(200, "ms"))
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
expectNoMsg(Duration.create(200, "ms"))
|
||||
|
||||
vehicle.Actor ! Vehicle.Reactivate
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
vehicle.Actor.tell(Vehicle.Reactivate(), probe.ref)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 1), probe.ref)
|
||||
val reply = probe.receiveOne(Duration.create(200, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlAlwaysDismountTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = new TestProbe(system).ref
|
||||
}
|
||||
vehicle.Weapons(2).Equipment.get.GUID = PlanetSideGUID(4)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"always allow dismount messages" in {
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
probe.receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 1), probe.ref)
|
||||
probe.receiveOne(Duration.create(100, "ms")) //discard
|
||||
|
||||
vehicle.Actor ! Mountable.TryDismount(player2, 1) //player2 requests dismount
|
||||
val reply1 = receiveOne(Duration.create(100, "ms"))
|
||||
vehicle.Actor.tell(Mountable.TryDismount(player2, 1), probe.ref) //player2 requests dismount
|
||||
val reply1 = probe.receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply1.isInstanceOf[Mountable.MountMessages])
|
||||
assert(reply1.asInstanceOf[Mountable.MountMessages].response.isInstanceOf[Mountable.CanDismount]) //player2 dismounts
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
|
||||
vehicle.Actor ! Mountable.TryDismount(player1, 0) //player1 requests dismount
|
||||
val reply2 = receiveOne(Duration.create(100, "ms"))
|
||||
vehicle.Actor.tell(Vehicle.PrepareForDeletion(), probe.ref)
|
||||
vehicle.Actor.tell(Mountable.TryDismount(player1, 0), probe.ref) //player1 requests dismount
|
||||
val reply2 = probe.receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply2.isInstanceOf[Mountable.MountMessages])
|
||||
assert(reply2.asInstanceOf[Mountable.MountMessages].response.isInstanceOf[Mountable.CanDismount]) //player1 dismounts
|
||||
}
|
||||
|
|
@ -391,8 +410,9 @@ class VehicleControlAlwaysDismountTest extends ActorTest {
|
|||
}
|
||||
|
||||
class VehicleControlMountingBlockedExosuitTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
def checkCanNotMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanNotMount])
|
||||
|
|
@ -402,7 +422,7 @@ class VehicleControlMountingBlockedExosuitTest extends ActorTest {
|
|||
}
|
||||
|
||||
def checkCanMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanMount])
|
||||
|
|
@ -410,49 +430,49 @@ class VehicleControlMountingBlockedExosuitTest extends ActorTest {
|
|||
assert(false)
|
||||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.ExoSuit = ExoSuitType.Reinforced
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.ExoSuit = ExoSuitType.MAX
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val player3 = Player(VehicleTest.avatar1)
|
||||
player3.ExoSuit = ExoSuitType.Agile
|
||||
player3.GUID = PlanetSideGUID(3)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"block players from sitting if their exo-suit is not allowed by the seat" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.ExoSuit = ExoSuitType.Reinforced
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.ExoSuit = ExoSuitType.MAX
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val player3 = Player(VehicleTest.avatar1)
|
||||
player3.ExoSuit = ExoSuitType.Agile
|
||||
player3.GUID = PlanetSideGUID(3)
|
||||
|
||||
//disallow
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0) //Reinforced in non-MAX seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref) //Reinforced in non-MAX seat
|
||||
checkCanNotMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 0) //MAX in non-Reinforced seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 0), probe.ref) //MAX in non-Reinforced seat
|
||||
checkCanNotMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1) //MAX in non-MAX seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 1), probe.ref) //MAX in non-MAX seat
|
||||
checkCanNotMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 9) //Reinforced in MAX-only seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 9), probe.ref) //Reinforced in MAX-only seat
|
||||
checkCanNotMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player3, 9) //Agile in MAX-only seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player3, 9), probe.ref) //Agile in MAX-only seat
|
||||
checkCanNotMount()
|
||||
|
||||
//allow
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 1)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 1), probe.ref)
|
||||
checkCanMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 9)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 9), probe.ref)
|
||||
checkCanMount()
|
||||
vehicle.Actor ! Mountable.TryMount(player3, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player3, 0), probe.ref)
|
||||
checkCanMount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlMountingBlockedSeatPermissionTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
def checkCanNotMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanNotMount])
|
||||
|
|
@ -462,7 +482,7 @@ class VehicleControlMountingBlockedSeatPermissionTest extends ActorTest {
|
|||
}
|
||||
|
||||
def checkCanMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanMount])
|
||||
|
|
@ -470,32 +490,33 @@ class VehicleControlMountingBlockedSeatPermissionTest extends ActorTest {
|
|||
assert(false)
|
||||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
"Vehicle Control" should {
|
||||
//11 June 2018: Group is not supported yet so do not bother testing it
|
||||
"block players from sitting if the seat does not allow it" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
vehicle.PermissionGroup(2,3) //passenger group -> empire
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 3) //passenger seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 3), probe.ref) //passenger seat
|
||||
checkCanMount()
|
||||
vehicle.PermissionGroup(2,0) //passenger group -> locked
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 4) //passenger seat
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 4), probe.ref) //passenger seat
|
||||
checkCanNotMount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlMountingDriverSeatTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
def checkCanMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanMount])
|
||||
|
|
@ -503,19 +524,18 @@ class VehicleControlMountingDriverSeatTest extends ActorTest {
|
|||
assert(false)
|
||||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"allow players to sit in the driver seat, even if it is locked, if the vehicle is unowned" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
|
||||
assert(vehicle.PermissionGroup(0).contains(VehicleLockState.Locked)) //driver group -> locked
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
assert(vehicle.Owner.isEmpty)
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
checkCanMount()
|
||||
assert(vehicle.Seats(0).Occupant.nonEmpty)
|
||||
}
|
||||
|
|
@ -523,8 +543,9 @@ class VehicleControlMountingDriverSeatTest extends ActorTest {
|
|||
}
|
||||
|
||||
class VehicleControlMountingOwnedLockedDriverSeatTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
def checkCanNotMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanNotMount])
|
||||
|
|
@ -534,7 +555,7 @@ class VehicleControlMountingOwnedLockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
|
||||
def checkCanMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanMount])
|
||||
|
|
@ -542,30 +563,28 @@ class VehicleControlMountingOwnedLockedDriverSeatTest extends ActorTest {
|
|||
assert(false)
|
||||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"block players that are not the current owner from sitting in the driver seat (locked)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
assert(vehicle.PermissionGroup(0).contains(VehicleLockState.Locked)) //driver group -> locked
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
vehicle.Owner = player1.GUID
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
checkCanMount()
|
||||
assert(vehicle.Seats(0).Occupant.nonEmpty)
|
||||
vehicle.Actor ! Mountable.TryDismount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor.tell(Mountable.TryDismount(player1, 0), probe.ref)
|
||||
probe.receiveOne(Duration.create(100, "ms")) //discard
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 0), probe.ref)
|
||||
checkCanNotMount()
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
}
|
||||
|
|
@ -573,8 +592,9 @@ class VehicleControlMountingOwnedLockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
|
||||
class VehicleControlMountingOwnedUnlockedDriverSeatTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
def checkCanMount() : Unit = {
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
val reply = probe.receiveOne(Duration.create(100, "ms"))
|
||||
reply match {
|
||||
case msg : Mountable.MountMessages =>
|
||||
assert(msg.response.isInstanceOf[Mountable.CanMount])
|
||||
|
|
@ -582,31 +602,29 @@ class VehicleControlMountingOwnedUnlockedDriverSeatTest extends ActorTest {
|
|||
assert(false)
|
||||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
"Vehicle Control" should {
|
||||
"allow players that are not the current owner to sit in the driver seat (empire)" in {
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar1)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
|
||||
vehicle.PermissionGroup(0,3) //passenger group -> empire
|
||||
assert(vehicle.PermissionGroup(0).contains(VehicleLockState.Empire)) //driver group -> empire
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
vehicle.Owner = player1.GUID //owner set
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player1, 0), probe.ref)
|
||||
checkCanMount()
|
||||
assert(vehicle.Seats(0).Occupant.nonEmpty)
|
||||
vehicle.Actor ! Mountable.TryDismount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor.tell(Mountable.TryDismount(player1, 0), probe.ref)
|
||||
probe.receiveOne(Duration.create(100, "ms")) //discard
|
||||
assert(vehicle.Seats(0).Occupant.isEmpty)
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 0)
|
||||
vehicle.Actor.tell(Mountable.TryMount(player2, 0), probe.ref)
|
||||
checkCanMount()
|
||||
assert(vehicle.Seats(0).Occupant.nonEmpty)
|
||||
}
|
||||
|
|
@ -614,26 +632,37 @@ class VehicleControlMountingOwnedUnlockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
|
||||
class VehicleControlShieldsChargingTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = probe.ref
|
||||
}
|
||||
|
||||
"charge vehicle shields" in {
|
||||
assert(vehicle.Shields == 0)
|
||||
assert(!vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
|
||||
val msg = receiveOne(500 milliseconds)
|
||||
assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge])
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
val msg = probe.receiveOne(500 milliseconds)
|
||||
assert(msg match {
|
||||
case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(vehicle.Shields == 15)
|
||||
assert(vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlShieldsNotChargingVehicleDeadTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = probe.ref
|
||||
}
|
||||
|
||||
"not charge vehicle shields if the vehicle is destroyed" in {
|
||||
assert(vehicle.Health > 0)
|
||||
|
|
@ -641,18 +670,22 @@ class VehicleControlShieldsNotChargingVehicleDeadTest extends ActorTest {
|
|||
assert(vehicle.Health == 0)
|
||||
assert(vehicle.Shields == 0)
|
||||
assert(!vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
vehicle.Actor.tell(Vehicle.ChargeShields(15), probe.ref)
|
||||
|
||||
expectNoMsg(1 seconds)
|
||||
probe.expectNoMsg(1 seconds)
|
||||
assert(vehicle.Shields == 0)
|
||||
assert(!vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlShieldsNotChargingVehicleShieldsFullTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = probe.ref
|
||||
}
|
||||
|
||||
"not charge vehicle shields if the vehicle is destroyed" in {
|
||||
assert(vehicle.Shields == 0)
|
||||
|
|
@ -661,54 +694,67 @@ class VehicleControlShieldsNotChargingVehicleShieldsFullTest extends ActorTest {
|
|||
assert(!vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
|
||||
expectNoMsg(1 seconds)
|
||||
probe.expectNoMsg(1 seconds)
|
||||
assert(!vehicle.History.exists({p => p.isInstanceOf[VehicleShieldCharge]}))
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlShieldsNotChargingTooEarlyTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = probe.ref
|
||||
}
|
||||
|
||||
"charge vehicle shields" in {
|
||||
assert(vehicle.Shields == 0)
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
|
||||
val msg = receiveOne(200 milliseconds)
|
||||
assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge])
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
val msg = probe.receiveOne(200 milliseconds)
|
||||
//assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge])
|
||||
assert(msg match {
|
||||
case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(vehicle.Shields == 15)
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
|
||||
expectNoMsg(200 milliseconds)
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
probe.expectNoMsg(200 milliseconds)
|
||||
assert(vehicle.Shields == 15)
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlShieldsNotChargingDamagedTest extends ActorTest {
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
//
|
||||
val beamer_wep = Tool(GlobalDefinitions.beamer)
|
||||
val p_source = PlayerSource( Player(Avatar("TestTarget", PlanetSideEmpire.NC, CharacterGender.Female, 1, CharacterVoice.Mute)) )
|
||||
val projectile = Projectile(beamer_wep.Projectile, GlobalDefinitions.beamer, beamer_wep.FireMode, p_source, GlobalDefinitions.beamer.ObjectId, Vector3.Zero, Vector3.Zero)
|
||||
val fury_dm = Vehicle(GlobalDefinitions.fury).DamageModel
|
||||
val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, p_source, fury_dm, Vector3(1.2f, 3.4f, 5.6f), System.nanoTime)
|
||||
|
||||
"not charge vehicle shields if recently damaged" in {
|
||||
assert(vehicle.Shields == 0)
|
||||
vehicle.Actor ! Vitality.Damage({case v : Vehicle => v.History(obj); obj })
|
||||
|
||||
val msg = receiveOne(200 milliseconds)
|
||||
assert(msg.isInstanceOf[Vitality.DamageResolution])
|
||||
assert(vehicle.Shields == 0)
|
||||
vehicle.Actor ! Vehicle.ChargeShields(15)
|
||||
|
||||
expectNoMsg(200 milliseconds)
|
||||
assert(vehicle.Shields == 0)
|
||||
}
|
||||
}
|
||||
//TODO implement message protocol for zone startup completion
|
||||
//class VehicleControlShieldsNotChargingDamagedTest extends ActorTest {
|
||||
// val probe = new TestProbe(system)
|
||||
// val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
// vehicle.GUID = PlanetSideGUID(10)
|
||||
// vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
// vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
// VehicleEvents = probe.ref
|
||||
// }
|
||||
// //
|
||||
// val beamer_wep = Tool(GlobalDefinitions.beamer)
|
||||
// val p_source = PlayerSource( Player(Avatar("TestTarget", PlanetSideEmpire.NC, CharacterGender.Female, 1, CharacterVoice.Mute)) )
|
||||
// val projectile = Projectile(beamer_wep.Projectile, GlobalDefinitions.beamer, beamer_wep.FireMode, p_source, GlobalDefinitions.beamer.ObjectId, Vector3.Zero, Vector3.Zero)
|
||||
// val fury_dm = Vehicle(GlobalDefinitions.fury).DamageModel
|
||||
// val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, p_source, fury_dm, Vector3(1.2f, 3.4f, 5.6f), System.nanoTime)
|
||||
//
|
||||
// "not charge vehicle shields if recently damaged" in {
|
||||
// assert(vehicle.Shields == 0)
|
||||
// vehicle.Actor.tell(Vitality.Damage({case v : Vehicle => v.History(obj); obj }), probe.ref)
|
||||
//
|
||||
// val msg = probe.receiveOne(200 milliseconds)
|
||||
// assert(msg.isInstanceOf[Vitality.DamageResolution])
|
||||
// assert(vehicle.Shields == 0)
|
||||
// vehicle.Actor.tell(Vehicle.ChargeShields(15), probe.ref)
|
||||
//
|
||||
// probe.expectNoMsg(200 milliseconds)
|
||||
// assert(vehicle.Shields == 0)
|
||||
// }
|
||||
//}
|
||||
|
||||
object VehicleTest {
|
||||
import net.psforever.objects.Avatar
|
||||
|
|
|
|||
|
|
@ -3326,15 +3326,15 @@ class WorldSessionActor extends Actor
|
|||
//player.Position = Vector3(4262.211f ,4067.0625f ,262.35938f) //z6, Akna.tower
|
||||
//player.Orientation = Vector3(0f, 0f, 132.1875f)
|
||||
// player.ExoSuit = ExoSuitType.MAX //TODO strange issue; divide number above by 10 when uncommenting
|
||||
player.Slot(0).Equipment = Tool(jammer_grenade) //Tool(GlobalDefinitions.StandardPistol(player.Faction))
|
||||
player.Slot(0).Equipment = Tool(GlobalDefinitions.StandardPistol(player.Faction))
|
||||
player.Slot(2).Equipment = Tool(suppressor)
|
||||
player.Slot(4).Equipment = Tool(GlobalDefinitions.StandardMelee(player.Faction))
|
||||
player.Slot(6).Equipment = ConstructionItem(ace) //AmmoBox(bullet_9mm)
|
||||
player.Slot(9).Equipment = ConstructionItem(ace) //AmmoBox(bullet_9mm)
|
||||
player.Slot(12).Equipment = ConstructionItem(ace) //AmmoBox(bullet_9mm)
|
||||
player.Slot(33).Equipment = ConstructionItem(ace) //AmmoBox(bullet_9mm_AP)
|
||||
player.Slot(36).Equipment = ConstructionItem(ace) //AmmoBox(GlobalDefinitions.StandardPistolAmmo(player.Faction))
|
||||
player.Slot(39).Equipment = Tool(jammer_grenade) //SimpleItem(remote_electronics_kit)
|
||||
player.Slot(6).Equipment = AmmoBox(bullet_9mm)
|
||||
player.Slot(9).Equipment = AmmoBox(bullet_9mm)
|
||||
player.Slot(12).Equipment = AmmoBox(bullet_9mm)
|
||||
player.Slot(33).Equipment = AmmoBox(bullet_9mm_AP)
|
||||
player.Slot(36).Equipment = AmmoBox(GlobalDefinitions.StandardPistolAmmo(player.Faction))
|
||||
player.Slot(39).Equipment = SimpleItem(remote_electronics_kit)
|
||||
player.Locker.Inventory += 0 -> SimpleItem(remote_electronics_kit)
|
||||
player.Inventory.Items.foreach { _.obj.Faction = faction }
|
||||
player.Actor = self
|
||||
|
|
@ -3741,9 +3741,6 @@ class WorldSessionActor extends Actor
|
|||
DeactivateImplants()
|
||||
}
|
||||
//implants and stamina management finish
|
||||
if(is_crouching && !player.Crouching) {
|
||||
// ...
|
||||
}
|
||||
player.Position = pos
|
||||
player.Velocity = vel
|
||||
player.Orientation = Vector3(player.Orientation.x, pitch, yaw)
|
||||
|
|
@ -10071,68 +10068,20 @@ class WorldSessionActor extends Actor
|
|||
projectilesToCleanUp(local_index) = false
|
||||
}
|
||||
|
||||
def FindJammerTargetsInScope(jammer : Any with JammingUnit) : Seq[PlanetSideGameObject] = {
|
||||
(jammer match {
|
||||
case p : ProjectileDefinition if !p.JammerProjectile => None
|
||||
case p => Some(p)
|
||||
}) match {
|
||||
case Some(p : JammingUnit) =>
|
||||
p.JammedEffectDuration
|
||||
.map { case (a, _) => a }
|
||||
.collect {
|
||||
case TargetValidation(EffectTarget.Category.Player, test) if test(player) => Some(player)
|
||||
case TargetValidation(EffectTarget.Category.Vehicle, test) if {
|
||||
continent.GUID(player.VehicleSeated) match {
|
||||
case Some(v) => test(v)
|
||||
case None => false
|
||||
}
|
||||
} => continent.GUID(player.VehicleSeated)
|
||||
case TargetValidation(EffectTarget.Category.Aircraft, test) if {
|
||||
continent.GUID(player.VehicleSeated) match {
|
||||
case Some(v) => test(v)
|
||||
case None => false
|
||||
}
|
||||
} => continent.GUID(player.VehicleSeated)
|
||||
} collect {
|
||||
case Some(a) => a
|
||||
} toSeq
|
||||
case _ =>
|
||||
Seq.empty[PlanetSideGameObject]
|
||||
}
|
||||
}
|
||||
|
||||
def CompileJammerTests(jammer : JammingUnit) : Iterable[EffectTarget.Validation.Value] = {
|
||||
jammer.JammedEffectDuration map { case (TargetValidation(_, test), _) => test }
|
||||
}
|
||||
|
||||
def CompileJammerTests(jammer : JammingUnit, target : EffectTarget.Category.Value) : Iterable[EffectTarget.Validation.Value] = {
|
||||
jammer.JammedEffectDuration collect { case (TargetValidation(filter, test), _) if filter == target => test }
|
||||
}
|
||||
|
||||
def FindJammerTargetsInScope(jammer : JammingUnit, scope : Seq[PlanetSideGUID], zone : Zone) : Seq[(PlanetSideGUID, PlanetSideGameObject)] = {
|
||||
val tests = CompileJammerTests(jammer)
|
||||
(for {
|
||||
uid <- scope
|
||||
obj = zone.GUID(uid)
|
||||
if obj.nonEmpty
|
||||
} yield (uid, obj.get))
|
||||
.collect {
|
||||
case out @ (_, b) if tests.foldLeft(false)(_ || _(b)) => out
|
||||
}
|
||||
}
|
||||
|
||||
def FindJammerTargetsInScope(jammer : JammingUnit, scope : Seq[PlanetSideGameObject]) : Seq[PlanetSideGameObject] = {
|
||||
val tests = CompileJammerTests(jammer)
|
||||
scope collect {
|
||||
case a if tests.foldLeft(false)(_ || _(a)) => a
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate all active implants.
|
||||
* This method is intended to support only the current Live server implants that are functional,
|
||||
* the darklight vision implant and the surge implant.
|
||||
*/
|
||||
def DeactivateImplants() : Unit = {
|
||||
DeactivateImplantDarkLight()
|
||||
DeactivateImplantSurge()
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the darklight vision implant.
|
||||
* This method is intended to support only the current Live server implants.
|
||||
*/
|
||||
def DeactivateImplantDarkLight() : Unit = {
|
||||
if(avatar.Implants(0).Active) {
|
||||
avatar.Implants(0).Active = false
|
||||
|
|
@ -10142,6 +10091,10 @@ class WorldSessionActor extends Actor
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the surge implant.
|
||||
* This method is intended to support only the current Live server implants.
|
||||
*/
|
||||
def DeactivateImplantSurge() : Unit = {
|
||||
if(avatar.Implants(1).Active) {
|
||||
avatar.Implants(1).Active = false
|
||||
|
|
@ -10151,34 +10104,39 @@ class WorldSessionActor extends Actor
|
|||
}
|
||||
}
|
||||
|
||||
override def TryJammerEffectActivate(target : Any, cause : ResolvedProjectile) : Unit = target match {
|
||||
case obj : Player =>
|
||||
val radius = cause.projectile.profile.DamageRadius
|
||||
JammingUnit.FindJammerDuration(cause.projectile.profile, obj) match {
|
||||
case Some(dur) if Vector3.DistanceSquared(cause.hit_pos, cause.target.Position) < radius * radius =>
|
||||
DeactivateImplants()
|
||||
skipStaminaRegenForTurns = 5
|
||||
StartJammeredSound(obj)
|
||||
StartJammeredStatus(obj, dur)
|
||||
case _ => ;
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the jammered buzzing.
|
||||
* @see `JammableHevaior.StartJammeredSound`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds;
|
||||
* by default, 30000
|
||||
*/
|
||||
override def StartJammeredSound(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : Player =>
|
||||
case obj : Player if !jammedSound =>
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, 27, 1))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(obj.GUID, 27, 1))
|
||||
super.StartJammeredSound(obj, dur)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a variety of tasks to indicate being jammered.
|
||||
* Deactivate implants (should also uninitialize them),
|
||||
* delay stamina regeneration for a certain number of turns,
|
||||
* and set the jammered status on specific holstered equipment.
|
||||
* @see `JammableHevaior.StartJammeredStatus`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds
|
||||
*/
|
||||
override def StartJammeredStatus(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : Player =>
|
||||
case obj : Player if !obj.Jammed =>
|
||||
DeactivateImplants()
|
||||
skipStaminaRegenForTurns = 10
|
||||
jammeredEquipment = (jammeredEquipment ++ obj.Holsters()
|
||||
.map { _.Equipment }
|
||||
.collect {
|
||||
case Some(item) if item.Size != EquipmentSize.Melee =>
|
||||
case Some(item : Tool) if item.Size != EquipmentSize.Melee =>
|
||||
item.Jammed = true
|
||||
sendResponse(PlanetsideAttributeMessage(item.GUID, 27, 1))
|
||||
item.GUID
|
||||
}).distinct
|
||||
|
|
@ -10186,17 +10144,33 @@ class WorldSessionActor extends Actor
|
|||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the jammered buzzing.
|
||||
* @see `JammableHevaior.CancelJammeredSound`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
*/
|
||||
override def CancelJammeredSound(target : Any) : Unit = target match {
|
||||
case obj : Player =>
|
||||
case obj : Player if jammedSound =>
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, 27, 0))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(obj.GUID, 27, 0))
|
||||
super.CancelJammeredSound(obj)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset jammered status of previously-affected equipment.
|
||||
* @see `JammableHevaior.CancelJammeredStatus`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
*/
|
||||
override def CancelJammeredStatus(target : Any) : Unit = target match {
|
||||
case obj : Player =>
|
||||
jammeredEquipment.foreach { id => sendResponse(PlanetsideAttributeMessage(id, 27, 0)) }
|
||||
case obj : Player if obj.Jammed =>
|
||||
jammeredEquipment.foreach { id =>
|
||||
continent.GUID(id) match {
|
||||
case Some(item : JammableUnit) => item.Jammed = false
|
||||
case _ => ;
|
||||
}
|
||||
sendResponse(PlanetsideAttributeMessage(id, 27, 0))
|
||||
}
|
||||
jammeredEquipment = Nil
|
||||
super.CancelJammeredStatus(obj)
|
||||
case _ => ;
|
||||
|
|
|
|||
Loading…
Reference in a new issue