mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-01 11:13:38 +00:00
Destroy and repair (#346)
* bog-standard order_terminal amenities now take damage up to the point of destruction and can be repaired from destruction to functional to the point of being fully repaired; this is mostly proof fo concept * restored proper destruction to FacilityTurrets; extended proper rrepairs to FacilityTurrets; co-opted terminal hacking into TerminalControl; started to expand on hacking protocol, but chose restraint * changes made thus that a clear Definition hierarchy is established; all of this is in line with making future changes to repair/destroy variables, and making generic the repair code * all meaningful facility amenities take damage and can be repaired; spawn tubes can be destroyed and the base will properly lose spawns (and show it on the map); some hack logic has been redistributed into the appropriate control objects, following in the wake of repair/damage logic * deployables are repairable; the TRAP has been converted into a ComplexDeployable; changed the nature of the Repairable traits * player bank repair and medapp heal has been moved out from WSA into PlayerControl * overhaul of Progress callback system and the inclusion of player revival as a Progress activity * begun relocating functionality for hacking outside of WSA; set up behavoir mixin for cargo operations, in order to move vehicle hack function, but did not yet integrate * integration of the actor behavior mixin for vehicle cargo operations to support the integration of vehicle hacking finalization * establishing inheritance/override potential of Damageable activity; Generator and SpawnTube map behavior behavior (currently inactive) * ImplantTerminalMech objects now have a 'with-coordinates' constructor and a deprecated 'no-coordinates' constructor; implants mechs and interfaces are now damageable and repairable, and their damage state can also block mounting * generators are destroyed and repaired properly, and even explode, killing a radius-worth of players * destroy and repair pass on deployables, except for explosive types * Damageable pass; client synchronization pass * helpful comments * some tests for damageable and repairable; refined output and repaired existing tests * enabled friendly fire check and recovery * handled friendly fire against allied mines; moved jammer code to common damageable behavior * tweaks to damageability, infantry heal and repair, and sensor and explosive animations * animations; framework for future vitals events; closing database connections * adding some deployable tests; fixing a bunch of other tests; History is back * testing for basic Damageable functions; removing a log message * finicky animation stuff * event messages to the Generator to represent health changes * damage against BFR's is now only used against mythical creatures * test fix
This commit is contained in:
parent
840006dca8
commit
c2f6baf551
124 changed files with 8530 additions and 2503 deletions
|
|
@ -4,7 +4,7 @@ package game
|
|||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGeneratorState}
|
||||
import scodec.bits._
|
||||
|
||||
class BuildingInfoUpdateMessageTest extends Specification {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import scodec.bits._
|
|||
|
||||
class DamageFeedbackMessageTest extends Specification {
|
||||
val string = hex"7b 3d842f610b2040000000"
|
||||
val string_2 = hex"7B 5E5826D8001DC0400000"
|
||||
|
||||
"decode" in {
|
||||
"decode (string 1)" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case DamageFeedbackMessage(unk1, unk2, unk2a, unk2b, unk2c, unk3, unk3a, unk3b, unk3c, unk3d, unk4, unk5, unk6) =>
|
||||
unk1 mustEqual 3
|
||||
|
|
@ -31,13 +32,41 @@ class DamageFeedbackMessageTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
"decode (string 2)" in {
|
||||
PacketCoding.DecodePacket(string_2).require match {
|
||||
case DamageFeedbackMessage(unk1, unk2, unk2a, unk2b, unk2c, unk3, unk3a, unk3b, unk3c, unk3d, unk4, unk5, unk6) =>
|
||||
unk1 mustEqual 5
|
||||
unk2 mustEqual true
|
||||
unk2a.contains(PlanetSideGUID(2454)) mustEqual true
|
||||
unk2b.isEmpty mustEqual true
|
||||
unk2c.isEmpty mustEqual true
|
||||
unk3 mustEqual false
|
||||
unk3a.contains(PlanetSideGUID(216)) mustEqual true
|
||||
unk3b.isEmpty mustEqual true
|
||||
unk3c.isEmpty mustEqual true
|
||||
unk3d.isEmpty mustEqual true
|
||||
unk4 mustEqual 0
|
||||
unk5 mustEqual 750
|
||||
unk6 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (string 1)" in {
|
||||
val msg = DamageFeedbackMessage(3, true, Some(PlanetSideGUID(2913)), None, None, true, Some(PlanetSideGUID(2913)), None, None, None, 1, 2, 0)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string
|
||||
}
|
||||
|
||||
"encode (string 2)" in {
|
||||
val msg = DamageFeedbackMessage(5, true, Some(PlanetSideGUID(2454)), None, None, false, Some(PlanetSideGUID(216)), None, None, None, 0, 750, 0)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_2
|
||||
}
|
||||
|
||||
"assert catches" in {
|
||||
//unk2: no parameters
|
||||
DamageFeedbackMessage(3, true, None, None, None, true, Some(PlanetSideGUID(2913)), None, None, None, 1, 2, 0) must throwA[AssertionError]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package objects
|
|||
import akka.actor.{ActorRef, Props}
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
|
||||
import net.psforever.objects.serverobject.structures._
|
||||
|
|
@ -17,8 +16,11 @@ import services.galaxy.GalaxyService
|
|||
import scala.concurrent.duration._
|
||||
|
||||
class AmenityTest extends Specification {
|
||||
val definition = new AmenityDefinition(0) {
|
||||
//intentionally blank
|
||||
}
|
||||
class AmenityObject extends Amenity {
|
||||
def Definition : ObjectDefinition = null
|
||||
def Definition : AmenityDefinition = definition
|
||||
}
|
||||
|
||||
"Amenity" should {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class DamageCalculationsTests extends Specification {
|
|||
}
|
||||
|
||||
"extract damage against something" in {
|
||||
DamageAgainstUnknown(proj_prof) mustEqual 66
|
||||
DamageAgainstBFR(proj_prof) mustEqual 66
|
||||
}
|
||||
|
||||
"extract a complete damage profile (1)" in {
|
||||
|
|
|
|||
1560
common/src/test/scala/objects/DamageableTest.scala
Normal file
1560
common/src/test/scala/objects/DamageableTest.scala
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,12 +2,23 @@
|
|||
package objects
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.ce.DeployedItem
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects.{TurretDeployable, _}
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.packet.game.{DeployableIcon, DeployableInfo, DeploymentAction}
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
import services.{RemoverActor, Service}
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import services.local.{LocalAction, LocalServiceMessage}
|
||||
import services.support.SupportActor
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -49,14 +60,14 @@ class ExplosiveDeployableTest extends Specification {
|
|||
"ExplosiveDeployable" should {
|
||||
"construct" in {
|
||||
val obj = new ExplosiveDeployable(GlobalDefinitions.he_mine)
|
||||
obj.Exploded mustEqual false
|
||||
obj.Destroyed mustEqual false
|
||||
}
|
||||
|
||||
"explode" in {
|
||||
val obj = new ExplosiveDeployable(GlobalDefinitions.he_mine)
|
||||
obj.Exploded mustEqual false
|
||||
obj.Exploded = true
|
||||
obj.Exploded mustEqual true
|
||||
obj.Destroyed mustEqual false
|
||||
obj.Destroyed = true
|
||||
obj.Destroyed mustEqual true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,15 +76,15 @@ class BoomerDeployableTest extends Specification {
|
|||
"BoomerDeployable" should {
|
||||
"construct" in {
|
||||
val obj = new BoomerDeployable(GlobalDefinitions.boomer)
|
||||
obj.Exploded mustEqual false
|
||||
obj.Destroyed mustEqual false
|
||||
obj.Trigger.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"explode" in {
|
||||
val obj = new BoomerDeployable(GlobalDefinitions.boomer)
|
||||
obj.Exploded mustEqual false
|
||||
obj.Exploded = true
|
||||
obj.Exploded mustEqual true
|
||||
obj.Destroyed mustEqual false
|
||||
obj.Destroyed = true
|
||||
obj.Destroyed mustEqual true
|
||||
}
|
||||
|
||||
"manage its trigger" in {
|
||||
|
|
@ -142,6 +153,130 @@ class TurretDeployableTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
class DeployableMake extends Specification {
|
||||
"Deployables.Make" should {
|
||||
"construct a boomer" in {
|
||||
val func = Deployables.Make(DeployedItem.boomer)
|
||||
func() match {
|
||||
case _ : BoomerDeployable => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct an he mine" in {
|
||||
val func = Deployables.Make(DeployedItem.he_mine)
|
||||
func() match {
|
||||
case obj : ExplosiveDeployable if obj.Definition == GlobalDefinitions.he_mine => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a disruptor mine" in {
|
||||
val func = Deployables.Make(DeployedItem.jammer_mine)
|
||||
func() match {
|
||||
case obj : ExplosiveDeployable if obj.Definition == GlobalDefinitions.jammer_mine => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a spitfire turret" in {
|
||||
val func = Deployables.Make(DeployedItem.spitfire_turret)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.spitfire_turret => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a shadow turret" in {
|
||||
val func = Deployables.Make(DeployedItem.spitfire_cloaked)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.spitfire_cloaked => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a cerebus turret" in {
|
||||
val func = Deployables.Make(DeployedItem.spitfire_aa)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.spitfire_aa => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a motion sensor" in {
|
||||
val func = Deployables.Make(DeployedItem.motionalarmsensor)
|
||||
func() match {
|
||||
case obj : SensorDeployable if obj.Definition == GlobalDefinitions.motionalarmsensor => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a sensor disruptor" in {
|
||||
val func = Deployables.Make(DeployedItem.sensor_shield)
|
||||
func() match {
|
||||
case obj : SensorDeployable if obj.Definition == GlobalDefinitions.sensor_shield => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct three metal i-beams so huge that a driver must be blind to drive into them but does anyway" in {
|
||||
val func = Deployables.Make(DeployedItem.tank_traps)
|
||||
func() match {
|
||||
case obj : TrapDeployable if obj.Definition == GlobalDefinitions.tank_traps => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a generic field turret" in {
|
||||
val func = Deployables.Make(DeployedItem.portable_manned_turret)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.portable_manned_turret => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct an avenger turret" in {
|
||||
val func = Deployables.Make(DeployedItem.portable_manned_turret_tr)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.portable_manned_turret_tr => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct an aegis shield generator" in {
|
||||
val func = Deployables.Make(DeployedItem.deployable_shield_generator)
|
||||
func() match {
|
||||
case obj : ShieldGeneratorDeployable if obj.Definition == GlobalDefinitions.deployable_shield_generator => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct a telepad" in {
|
||||
val func = Deployables.Make(DeployedItem.router_telepad_deployable)
|
||||
func() match {
|
||||
case obj : TelepadDeployable if obj.Definition == GlobalDefinitions.router_telepad_deployable => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct an osprey turret" in {
|
||||
val func = Deployables.Make(DeployedItem.portable_manned_turret_nc)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.portable_manned_turret_nc => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"construct an orion turret" in {
|
||||
val func = Deployables.Make(DeployedItem.portable_manned_turret_vs)
|
||||
func() match {
|
||||
case obj : TurretDeployable if obj.Definition == GlobalDefinitions.portable_manned_turret_vs => ok
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ShieldGeneratorDeployableTest extends Specification {
|
||||
"ShieldGeneratorDeployable" should {
|
||||
"construct" in {
|
||||
|
|
@ -158,6 +293,291 @@ class ShieldGeneratorDeployableTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class ExplosiveDeployableJammerTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val localProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
zone.LocalEvents = localProbe.ref
|
||||
|
||||
val j_mine = Deployables.Make(DeployedItem.jammer_mine)().asInstanceOf[ExplosiveDeployable] //guid=1
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=4
|
||||
player2.Spawn
|
||||
val weapon = Tool(GlobalDefinitions.jammer_grenade) //guid=5
|
||||
guid.register(j_mine, 1)
|
||||
guid.register(player1, 3)
|
||||
guid.register(player2, 4)
|
||||
guid.register(weapon, 5)
|
||||
j_mine.Zone = zone
|
||||
j_mine.Owner = player2
|
||||
j_mine.OwnerName = player2.Name
|
||||
j_mine.Faction = PlanetSideEmpire.NC
|
||||
j_mine.Actor = system.actorOf(Props(classOf[ExplosiveDeployableControl], j_mine), "j-mine-control")
|
||||
|
||||
val jMineSource = SourceEntry(j_mine)
|
||||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
jMineSource,
|
||||
j_mine.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageToJ = resolved.damage_model.Calculate(resolved)
|
||||
|
||||
"ExplosiveDeployable" should {
|
||||
"handle being jammered appropriately (no detonation)" in {
|
||||
assert(!j_mine.Destroyed)
|
||||
|
||||
j_mine.Actor ! Vitality.Damage(applyDamageToJ)
|
||||
val msg_local = localProbe.receiveN(4, 200 milliseconds)
|
||||
val msg_avatar = avatarProbe.receiveOne(200 milliseconds)
|
||||
activityProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_local.head match {
|
||||
case LocalServiceMessage("TestCharacter2", LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target)) => target eq j_mine
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(1) match {
|
||||
case LocalServiceMessage("NC", LocalAction.DeployableMapIcon(
|
||||
PlanetSideGUID(0),
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, _, PlanetSideGUID(0))
|
||||
)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(2) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) => (target eq j_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(3) match {
|
||||
case LocalServiceMessage.Deployables(RemoverActor.AddTask(target, _zone, _)) => (target eq j_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar match {
|
||||
case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(1), _, Service.defaultPlayerGUID, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(j_mine.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExplosiveDeployableJammerExplodeTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val localProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
zone.LocalEvents = localProbe.ref
|
||||
|
||||
val h_mine = Deployables.Make(DeployedItem.he_mine)().asInstanceOf[ExplosiveDeployable] //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=4
|
||||
player2.Spawn
|
||||
val weapon = Tool(GlobalDefinitions.jammer_grenade) //guid=5
|
||||
guid.register(h_mine, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(player2, 4)
|
||||
guid.register(weapon, 5)
|
||||
h_mine.Zone = zone
|
||||
h_mine.Owner = player2
|
||||
h_mine.OwnerName = player2.Name
|
||||
h_mine.Faction = PlanetSideEmpire.NC
|
||||
h_mine.Actor = system.actorOf(Props(classOf[ExplosiveDeployableControl], h_mine), "h-mine-control")
|
||||
|
||||
val hMineSource = SourceEntry(h_mine)
|
||||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
hMineSource,
|
||||
h_mine.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageToH = resolved.damage_model.Calculate(resolved)
|
||||
|
||||
"ExplosiveDeployable" should {
|
||||
"handle being jammered appropriately (detonation)" in {
|
||||
assert(!h_mine.Destroyed)
|
||||
|
||||
h_mine.Actor ! Vitality.Damage(applyDamageToH)
|
||||
val msg_local = localProbe.receiveN(5, 200 milliseconds)
|
||||
val msg_avatar = avatarProbe.receiveOne(200 milliseconds)
|
||||
val msg_activity = activityProbe.receiveOne(200 milliseconds)
|
||||
assert(
|
||||
msg_local.head match {
|
||||
case LocalServiceMessage("test", LocalAction.Detonate(PlanetSideGUID(2), target)) => target eq h_mine
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(1) match {
|
||||
case LocalServiceMessage("TestCharacter2", LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target)) => target eq h_mine
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(2) match {
|
||||
case LocalServiceMessage("NC", LocalAction.DeployableMapIcon(
|
||||
PlanetSideGUID(0),
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0))
|
||||
)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(3) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) => (target eq h_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(4) match {
|
||||
case LocalServiceMessage.Deployables(RemoverActor.AddTask(target, _zone, _)) => (target eq h_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar match {
|
||||
case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, Service.defaultPlayerGUID, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_activity match {
|
||||
case Zone.HotSpot.Activity(target, attacker, _) => (target eq hMineSource) && (attacker eq pSource)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(h_mine.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExplosiveDeployableDestructionTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val localProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
zone.LocalEvents = localProbe.ref
|
||||
|
||||
val h_mine = Deployables.Make(DeployedItem.he_mine)().asInstanceOf[ExplosiveDeployable] //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=4
|
||||
player2.Spawn
|
||||
val weapon = Tool(GlobalDefinitions.suppressor) //guid=5
|
||||
guid.register(h_mine, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(player2, 4)
|
||||
guid.register(weapon, 5)
|
||||
h_mine.Zone = zone
|
||||
h_mine.Owner = player2
|
||||
h_mine.OwnerName = player2.Name
|
||||
h_mine.Faction = PlanetSideEmpire.NC
|
||||
h_mine.Actor = system.actorOf(Props(classOf[ExplosiveDeployableControl], h_mine), "h-mine-control")
|
||||
|
||||
val hMineSource = SourceEntry(h_mine)
|
||||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
hMineSource,
|
||||
h_mine.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
|
||||
"ExplosiveDeployable" should {
|
||||
"handle being destroyed" in {
|
||||
h_mine.Health = h_mine.Definition.DamageDestroysAt + 1
|
||||
assert(h_mine.Health > h_mine.Definition.DamageDestroysAt)
|
||||
assert(!h_mine.Destroyed)
|
||||
|
||||
h_mine.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_local = localProbe.receiveN(5, 200 milliseconds)
|
||||
val msg_avatar = avatarProbe.receiveOne(200 milliseconds)
|
||||
activityProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_local.head match {
|
||||
case LocalServiceMessage("TestCharacter2", LocalAction.AlertDestroyDeployable(PlanetSideGUID(0), target)) => target eq h_mine
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(1) match {
|
||||
case LocalServiceMessage("NC", LocalAction.DeployableMapIcon(
|
||||
PlanetSideGUID(0),
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0))
|
||||
)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(2) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) => (target eq h_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(3) match {
|
||||
case LocalServiceMessage.Deployables(RemoverActor.AddTask(target, _zone, _)) => (target eq h_mine) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_local(4) match {
|
||||
case LocalServiceMessage("test", LocalAction.TriggerEffect(_, "detonate_damaged_mine", PlanetSideGUID(2))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar match {
|
||||
case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, Service.defaultPlayerGUID, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(h_mine.Health <= h_mine.Definition.DamageDestroysAt)
|
||||
assert(h_mine.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
class TurretControlConstructTest extends ActorTest {
|
||||
"TurretControl" should {
|
||||
"construct" in {
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Tool}
|
||||
import net.psforever.objects.definition.ToolDefinition
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.serverobject.turret._
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.{InventoryStateMessage, RepairMessage}
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -22,7 +29,7 @@ class FacilityTurretTest extends Specification {
|
|||
obj.Weapons mustEqual mutable.HashMap.empty[TurretUpgrade.Value, ToolDefinition]
|
||||
obj.ReserveAmmunition mustEqual false
|
||||
obj.FactionLocked mustEqual true
|
||||
obj.MaxHealth mustEqual 100
|
||||
obj.MaxHealth mustEqual 0
|
||||
obj.MountPoints mustEqual mutable.HashMap.empty[Int,Int]
|
||||
}
|
||||
|
||||
|
|
@ -36,17 +43,13 @@ class FacilityTurretTest extends Specification {
|
|||
ko
|
||||
}
|
||||
obj.Seats.size mustEqual 1
|
||||
obj.Seats(0).ControlledWeapon mustEqual Some(1)
|
||||
obj.Seats(0).ControlledWeapon.contains(1) mustEqual true
|
||||
obj.MountPoints.size mustEqual 1
|
||||
obj.MountPoints(1) mustEqual 0
|
||||
obj.Health mustEqual 3600
|
||||
obj.Upgrade mustEqual TurretUpgrade.None
|
||||
obj.Jammered mustEqual false
|
||||
|
||||
obj.Health = 360
|
||||
obj.Health mustEqual 360
|
||||
obj.Jammered = true
|
||||
obj.Jammered mustEqual true
|
||||
}
|
||||
|
||||
"upgrade to a different weapon" in {
|
||||
|
|
@ -176,3 +179,97 @@ class FacilityTurretControl4Test extends ActorTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FacilityTurretControlRestorationTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val vehicleProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
zone.VehicleEvents = vehicleProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
val turret = new FacilityTurret(GlobalDefinitions.manned_turret) //2, 5, 6
|
||||
turret.Actor = system.actorOf(Props(classOf[FacilityTurretControl], turret), "turret-control")
|
||||
turret.Zone = zone
|
||||
turret.Position = Vector3(1, 0, 0)
|
||||
val turretWeapon = turret.Weapons.values.head.Equipment.get.asInstanceOf[Tool]
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 2, 2)
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(turret, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(turretWeapon, 5)
|
||||
guid.register(turretWeapon.AmmoSlot.Box, 6)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = turret
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //7 & 8
|
||||
guid.register(tool, 7)
|
||||
guid.register(tool.AmmoSlot.Box, 8)
|
||||
|
||||
"RepairableTurretWeapon" should {
|
||||
"handle repairs and restoration" in {
|
||||
turret.Health = turret.Definition.RepairRestoresAt - 1 //initial state manip
|
||||
turret.Destroyed = true //initial state manip
|
||||
assert(turret.Health < turret.Definition.RepairRestoresAt)
|
||||
assert(turret.Destroyed)
|
||||
|
||||
turret.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg12345 = avatarProbe.receiveN(5, 500 milliseconds)
|
||||
val msg4 = vehicleProbe.receiveOne(500 milliseconds)
|
||||
assert(
|
||||
msg12345.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(2) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 50, 0)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(3) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 51, 0)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(4) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg4 match {
|
||||
case VehicleServiceMessage("test", VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(turret.Health > turret.Definition.RepairRestoresAt)
|
||||
assert(!turret.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
766
common/src/test/scala/objects/GeneratorTest.scala
Normal file
766
common/src/test/scala/objects/GeneratorTest.scala
Normal file
|
|
@ -0,0 +1,766 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Tool}
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.generator.{Generator, GeneratorControl}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.{InventoryStateMessage, RepairMessage, TriggerEffectMessage}
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class GeneratorTest extends Specification {
|
||||
"Generator" should {
|
||||
"construct" in {
|
||||
Generator(GlobalDefinitions.generator)
|
||||
ok
|
||||
}
|
||||
|
||||
"start in 'Normal' condition" in {
|
||||
val obj = Generator(GlobalDefinitions.generator)
|
||||
obj.Condition mustEqual PlanetSideGeneratorState.Normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlConstructTest extends ActorTest {
|
||||
"GeneratorControl" should {
|
||||
"construct" in {
|
||||
val gen = Generator(GlobalDefinitions.generator)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "gen-control")
|
||||
assert(gen.Actor != ActorRef.noSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"handle damage" in {
|
||||
assert(gen.Health == gen.Definition.MaxHealth)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 15)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health < gen.Definition.MaxHealth)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlCriticalTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
val halfHealth = gen.Definition.MaxHealth / 2
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"handle damage through the generator's critical state" in {
|
||||
gen.Health = halfHealth + 1 //no matter what, the next shot pushes it to critical status
|
||||
assert(gen.Health > halfHealth)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
val msg_building = buildingProbe.receiveOne(500 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 15)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_building match {
|
||||
case Building.AmenityStateChange(o) => o eq gen
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health < halfHealth)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Critical)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlDestroyedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
player1.Actor = TestProbe().ref
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"handle damage until destroyed" in {
|
||||
gen.Health = 1 //no matter what, the next shot destroys the generator
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal) //skipped critical state because didn't transition ~50%
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar1 = avatarProbe.receiveOne(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar1 match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 16)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
|
||||
avatarProbe.expectNoMsg(9 seconds)
|
||||
buildingProbe.expectNoMsg(50 milliseconds) //no prior messages
|
||||
val msg_avatar2 = avatarProbe.receiveN(3, 1000 milliseconds) //see DamageableEntity test file
|
||||
val msg_building = buildingProbe.receiveOne(200 milliseconds)
|
||||
assert(
|
||||
msg_building match {
|
||||
case Building.AmenityStateChange(o) => o eq gen
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(2) match {
|
||||
case AvatarServiceMessage("test",
|
||||
AvatarAction.SendResponse(_, TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))
|
||||
) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 0)
|
||||
assert(gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlKillsTest extends ActorTest {
|
||||
/*
|
||||
to perform this test, players need to be added to the SOI organization of the test base in proximity of the generator
|
||||
under normal player scenario, this is an automatic process
|
||||
extending from the act of players being in a zone
|
||||
and players being within the SOI radius from the center of a facility on a periodic check
|
||||
the test base being used has no established SOI region or automatic SOI check refresh,
|
||||
but its SOI information can be loaded with the players manually
|
||||
the players need something to catch the die message
|
||||
*/
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.TR, CharacterGender.Female, 1, CharacterVoice.Mute)) //guid=4
|
||||
player2.Position = Vector3(15, 0, 0) //>14m from generator; lives
|
||||
player2.Spawn
|
||||
val player2Probe = TestProbe()
|
||||
player2.Actor = player2Probe.ref
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1, player2)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(player2, 4)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"kill players when the generator is destroyed" in {
|
||||
gen.Health = 1 //no matter what, the next shot destroys the generator
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal) //skipped critical state because didn't transition ~50%
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar1 = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
player2Probe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar1.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 16)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar1(1) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 16)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
|
||||
val msg_building = buildingProbe.receiveOne(10500 milliseconds)
|
||||
val msg_avatar2 = avatarProbe.receiveN(3, 200 milliseconds)
|
||||
val msg_player1 = player1Probe.receiveOne(100 milliseconds)
|
||||
player2Probe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_building match {
|
||||
case Building.AmenityStateChange(o) => o eq gen
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(2) match {
|
||||
case AvatarServiceMessage("test",
|
||||
AvatarAction.SendResponse(_, TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))
|
||||
) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_player1 match {
|
||||
case _ @ Player.Die() => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 0)
|
||||
assert(gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlNotDestroyTwice extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"not send a status update if destroyed and partially repaired, but destroyed again" in {
|
||||
//damaged, not yet restored, but will not be destroyed again within one shot
|
||||
val originalHealth = gen.Health = gen.Definition.DamageDestroysAt + 1
|
||||
gen.Condition = PlanetSideGeneratorState.Destroyed //initial state manip
|
||||
gen.Destroyed = true
|
||||
assert(gen.Destroyed)
|
||||
assert(originalHealth < gen.Definition.DefaultHealth)
|
||||
assert(originalHealth < gen.Definition.RepairRestoresAt)
|
||||
assert(originalHealth > gen.Definition.DamageDestroysAt)
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
activityProbe.receiveOne(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(1000 milliseconds)
|
||||
assert(gen.Health < originalHealth)
|
||||
assert(gen.Destroyed)
|
||||
assert(originalHealth < gen.Definition.DefaultHealth)
|
||||
assert(originalHealth < gen.Definition.RepairRestoresAt)
|
||||
assert(gen.Health <= gen.Definition.DamageDestroysAt)
|
||||
|
||||
//damaged, not yet restored, and would have been destroyed with next shot
|
||||
gen.Health = 1
|
||||
assert(gen.Health == 1)
|
||||
assert(gen.Destroyed)
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
activityProbe.receiveOne(500 milliseconds) //activity alert occurs because this was not a kill shot
|
||||
buildingProbe.expectNoMsg(1000 milliseconds)
|
||||
assert(gen.Health == 0)
|
||||
assert(gen.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlNotDamageIfExplodingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"not damage if the generator is going to explode" in {
|
||||
gen.Health = 1 //no matter what, the next shot destroys the generator
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal) //skipped critical state because didn't transition ~50%
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveOne(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 16)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
//going to explode state
|
||||
|
||||
//once
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(gen.Health == 1)
|
||||
//twice
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(gen.Health == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlNotRepairIfExplodingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
|
||||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(gen),
|
||||
gen.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //4 & 5
|
||||
guid.register(tool, 4)
|
||||
guid.register(tool.AmmoSlot.Box, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"not repair if the generator is going to explode" in {
|
||||
gen.Health = 1 //no matter what, the next shot destroys the generator
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal) //skipped critical state because didn't transition ~50%
|
||||
|
||||
gen.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar1 = avatarProbe.receiveOne(500 milliseconds)
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar1 match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 16)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Health == 1)
|
||||
assert(!gen.Destroyed)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
//going to explode state
|
||||
|
||||
//once
|
||||
gen.Actor ! CommonMessages.Use(player1, Some(tool)) //repair?
|
||||
avatarProbe.expectNoMsg(1000 milliseconds) //no messages
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(gen.Health == 1)
|
||||
//twice
|
||||
gen.Actor ! CommonMessages.Use(player1, Some(tool)) //repair?
|
||||
avatarProbe.expectNoMsg(1000 milliseconds) //no messages
|
||||
buildingProbe.expectNoMsg(200 milliseconds)
|
||||
player1Probe.expectNoMsg(200 milliseconds)
|
||||
assert(gen.Health == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratorControlRepairPastRestorePoint extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = { }
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Position = Vector3(14, 0, 0) //<14m from generator; dies
|
||||
player1.Spawn
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
building.PlayersInSOI = List(player1)
|
||||
val buildingProbe = TestProbe()
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //4 & 5
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(tool, 4)
|
||||
guid.register(tool.AmmoSlot.Box, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"GeneratorControl" should {
|
||||
"send a status update if destroyed and repairing past the restoration point" in {
|
||||
val originalHealth = gen.Health = gen.Definition.RepairRestoresAt - 1 //damage
|
||||
gen.Condition = PlanetSideGeneratorState.Destroyed //initial state manip
|
||||
gen.Destroyed = true
|
||||
assert(originalHealth < gen.Definition.DefaultHealth)
|
||||
assert(originalHealth < gen.Definition.RepairRestoresAt)
|
||||
assert(gen.Destroyed)
|
||||
|
||||
gen.Actor ! CommonMessages.Use(player1, Some(tool)) //repair
|
||||
val msg_avatar = avatarProbe.receiveN(4, 500 milliseconds) //expected
|
||||
val msg_building = buildingProbe.receiveOne(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(_, InventoryStateMessage(ValidPlanetSideGUID(5), _, ValidPlanetSideGUID(4), _))
|
||||
) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.GenericObjectAction(_, PlanetSideGUID(1), 17)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(3) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, RepairMessage(ValidPlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_building match {
|
||||
case Building.AmenityStateChange(o) => o eq gen
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(gen.Condition == PlanetSideGeneratorState.Normal)
|
||||
assert(gen.Health > gen.Definition.RepairRestoresAt)
|
||||
assert(!gen.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ class IFFLockControl2Test extends ActorTest {
|
|||
player.GUID = PlanetSideGUID(1)
|
||||
assert(lock.HackedBy.isEmpty)
|
||||
|
||||
lock.Actor ! CommonMessages.Hack(player)
|
||||
lock.Actor ! CommonMessages.Hack(player, lock)
|
||||
Thread.sleep(500L) //blocking
|
||||
assert(lock.HackedBy.nonEmpty) //TODO rewrite later
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ class IFFLockControl3Test extends ActorTest {
|
|||
player.GUID = PlanetSideGUID(1)
|
||||
assert(lock.HackedBy.isEmpty)
|
||||
|
||||
lock.Actor ! CommonMessages.Hack(player)
|
||||
lock.Actor ! CommonMessages.Hack(player, lock)
|
||||
Thread.sleep(500L) //blocking
|
||||
assert(lock.HackedBy.nonEmpty) //TODO rewrite later
|
||||
lock.Actor ! CommonMessages.ClearHack()
|
||||
|
|
|
|||
599
common/src/test/scala/objects/PlayerControlTest.scala
Normal file
599
common/src/test/scala/objects/PlayerControlTest.scala
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.avatar.PlayerControl
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types._
|
||||
import services.Service
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class PlayerControlHealTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 0, 0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=2
|
||||
player2.Zone = zone
|
||||
player2.Spawn
|
||||
player2.Actor = system.actorOf(Props(classOf[PlayerControl], player2), "player2-control")
|
||||
|
||||
val tool = Tool(GlobalDefinitions.medicalapplicator) //guid=3 & 4
|
||||
|
||||
guid.register(player1, 1)
|
||||
guid.register(player2, 2)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle being healed by another player" in {
|
||||
val originalHealth = player2.Health = 0 //initial state manip
|
||||
val originalMagazine = tool.Magazine
|
||||
assert(originalHealth < player2.MaxHealth)
|
||||
|
||||
player2.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar = avatarProbe.receiveN(4, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 55, 1)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(3) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
val raisedHealth = player2.Health
|
||||
assert(raisedHealth > originalHealth)
|
||||
assert(tool.Magazine < originalMagazine)
|
||||
|
||||
player1.Position = Vector3(10,0,0) //moved more than 5m away
|
||||
player2.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
assert(raisedHealth == player2.Health)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlHealSelfTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 0, 0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
|
||||
val tool = Tool(GlobalDefinitions.medicalapplicator) //guid=3 & 4
|
||||
|
||||
guid.register(player1, 1)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle healing own self" in {
|
||||
val originalHealth = player1.Health = 1 //initial state manip
|
||||
val originalMagazine = tool.Magazine
|
||||
assert(originalHealth < player1.MaxHealth)
|
||||
|
||||
player1.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar1 = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar1.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar1(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
val raisedHealth = player1.Health
|
||||
assert(raisedHealth > originalHealth)
|
||||
assert(tool.Magazine < originalMagazine)
|
||||
|
||||
player1.Position = Vector3(10,0,0) //trying to move away from oneself doesn't work
|
||||
player1.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar2 = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar2.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player1.Health > raisedHealth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 0, 0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=2
|
||||
player2.Zone = zone
|
||||
player2.Spawn
|
||||
player2.Actor = system.actorOf(Props(classOf[PlayerControl], player2), "player2-control")
|
||||
|
||||
val tool = Tool(GlobalDefinitions.bank) //guid=3 & 4
|
||||
|
||||
guid.register(player1, 1)
|
||||
guid.register(player2, 2)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle being repaired by another player" in {
|
||||
val originalArmor = player2.Armor = 0 //initial state manip
|
||||
val originalMagazine = tool.Magazine
|
||||
assert(originalArmor < player2.MaxArmor)
|
||||
|
||||
player2.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar = avatarProbe.receiveN(5, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 56, 1)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(3) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(4) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 56, 1)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player2.Armor > originalArmor)
|
||||
assert(tool.Magazine < originalMagazine)
|
||||
|
||||
val fixedArmor = player2.Armor
|
||||
player1.Position = Vector3(10,0,0) //moved more than 5m away
|
||||
player2.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
assert(fixedArmor == player2.Armor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlRepairSelfTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 0, 0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
|
||||
val tool = Tool(GlobalDefinitions.bank) //guid=3 & 4
|
||||
|
||||
guid.register(player1, 1)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle repairing own self" in {
|
||||
val originalArmor = player1.Armor = 0 //initial state manip
|
||||
val originalMagazine = tool.Magazine
|
||||
assert(originalArmor < player1.MaxArmor)
|
||||
|
||||
player1.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar1 = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar1.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar1(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 4, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
val fixedArmor = player1.Armor
|
||||
assert(fixedArmor > originalArmor)
|
||||
assert(tool.Magazine < originalMagazine)
|
||||
|
||||
player1.Position = Vector3(10,0,0) //trying to move away from oneself doesn't work
|
||||
player1.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg_avatar2 = avatarProbe.receiveN(2, 500 milliseconds)
|
||||
assert(
|
||||
msg_avatar2.head match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar2(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 4, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player1.Armor > fixedArmor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 0, 0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=2
|
||||
player2.Zone = zone
|
||||
player2.Spawn
|
||||
player2.Actor = system.actorOf(Props(classOf[PlayerControl], player2), "player2-control")
|
||||
val tool = Tool(GlobalDefinitions.suppressor) //guid 3 & 4
|
||||
val projectile = tool.Projectile
|
||||
val playerSource = SourceEntry(player2)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, tool.Definition, tool.FireMode, PlayerSource(player1), 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
playerSource,
|
||||
player1.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
guid.register(player1, 1)
|
||||
guid.register(player2, 2)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
expectNoMsg(200 milliseconds)
|
||||
"PlayerControl" should {
|
||||
"handle damage" in {
|
||||
assert(player2.Health == player2.Definition.DefaultHealth)
|
||||
assert(player2.Armor == player2.MaxArmor)
|
||||
player2.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveN(3, 500 milliseconds)
|
||||
val msg_activity = activityProbe.receiveOne(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_activity match {
|
||||
case activity : Zone.HotSpot.Activity =>
|
||||
activity.attacker == PlayerSource(player1) &&
|
||||
activity.defender == playerSource &&
|
||||
activity.location == Vector3(1, 0, 0)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(10, Vector3(2, 0, 0)))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player2.Health < player2.Definition.DefaultHealth)
|
||||
assert(player2.Armor < player2.MaxArmor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlDeathStandingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2,0,0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=2
|
||||
player2.Zone = zone
|
||||
player2.Spawn
|
||||
player2.Actor = system.actorOf(Props(classOf[PlayerControl], player2), "player2-control")
|
||||
|
||||
val tool = Tool(GlobalDefinitions.suppressor) //guid 3 & 4
|
||||
val projectile = tool.Projectile
|
||||
val player1Source = SourceEntry(player1)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, tool.Definition, tool.FireMode, player1Source, 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(player2),
|
||||
player2.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
guid.register(player1, 1)
|
||||
guid.register(player2, 2)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
expectNoMsg(200 milliseconds)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle death" in {
|
||||
player2.Health = player2.Definition.DamageDestroysAt + 1 //initial state manip
|
||||
player2.ExoSuit = ExoSuitType.MAX
|
||||
player2.Armor = 1 //initial state manip
|
||||
player2.Capacitor = 1 //initial state manip
|
||||
assert(player2.Health > player2.Definition.DamageDestroysAt)
|
||||
assert(player2.Armor == 1)
|
||||
assert(player2.Capacitor == 1)
|
||||
assert(player2.isAlive)
|
||||
|
||||
player2.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveN(8, 500 milliseconds)
|
||||
activityProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.Killed(PlanetSideGUID(2))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(3) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 2, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(4) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 7, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(5) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(_, DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(2), _, Vector3.Zero))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(6) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(_, AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, Vector3.Zero, PlanetSideEmpire.NC, true))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(7) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.DestroyDisplay(killer, victim, _, _))
|
||||
if killer == player1Source && victim == PlayerSource(player2) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player2.Health <= player2.Definition.DamageDestroysAt)
|
||||
assert(player2.Armor == 0)
|
||||
assert(!player2.isAlive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerControlDeathSeatedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
val activityProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=1
|
||||
player1.Zone = zone
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2,0,0)
|
||||
player1.Actor = system.actorOf(Props(classOf[PlayerControl], player1), "player1-control")
|
||||
val player2 = Player(Avatar("TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=2
|
||||
player2.Zone = zone
|
||||
player2.Spawn
|
||||
player2.Actor = system.actorOf(Props(classOf[PlayerControl], player2), "player2-control")
|
||||
|
||||
val vehicle = Vehicle(GlobalDefinitions.quadstealth) //guid=5
|
||||
vehicle.Faction = player2.Faction
|
||||
|
||||
val tool = Tool(GlobalDefinitions.suppressor) //guid 3 & 4
|
||||
val projectile = tool.Projectile
|
||||
val player1Source = SourceEntry(player1)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, tool.Definition, tool.FireMode, player1Source, 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(player2),
|
||||
player2.DamageModel,
|
||||
Vector3(1, 0, 0)
|
||||
)
|
||||
val applyDamageTo = resolved.damage_model.Calculate(resolved)
|
||||
guid.register(player1, 1)
|
||||
guid.register(player2, 2)
|
||||
guid.register(tool, 3)
|
||||
guid.register(tool.AmmoSlot.Box, 4)
|
||||
guid.register(vehicle, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
|
||||
"PlayerControl" should {
|
||||
"handle death when seated (in something)" in {
|
||||
player2.Health = player2.Definition.DamageDestroysAt + 1 //initial state manip
|
||||
player2.VehicleSeated = vehicle.GUID //initial state manip, anything
|
||||
vehicle.Seats(0).Occupant = player2
|
||||
player2.Armor = 0 //initial state manip
|
||||
assert(player2.Health > player2.Definition.DamageDestroysAt)
|
||||
assert(player2.isAlive)
|
||||
|
||||
player2.Actor ! Vitality.Damage(applyDamageTo)
|
||||
val msg_avatar = avatarProbe.receiveN(9, 500 milliseconds)
|
||||
activityProbe.expectNoMsg(200 milliseconds)
|
||||
assert(
|
||||
msg_avatar.head match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.Killed(PlanetSideGUID(2))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(1) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(_,
|
||||
ObjectDetachMessage(PlanetSideGUID(5), PlanetSideGUID(2), _, _, _, _))
|
||||
) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(2) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 29, 1)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(3) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(2), PlanetSideGUID(2), _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(4) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(5) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 2, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(6) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(_, DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(2), _, Vector3.Zero))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(7) match {
|
||||
case AvatarServiceMessage("TestCharacter2", AvatarAction.SendResponse(_, AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, Vector3.Zero, PlanetSideEmpire.NC, true))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg_avatar(8) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.DestroyDisplay(killer, victim, _, _))
|
||||
if killer == player1Source && victim == PlayerSource(player2) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(player2.Health <= player2.Definition.DamageDestroysAt)
|
||||
assert(!player2.isAlive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object PlayerControlTest { }
|
||||
|
|
@ -127,9 +127,12 @@ class PlayerTest extends Specification {
|
|||
obj.MaxStamina mustEqual 100
|
||||
obj.MaxHealth = 123
|
||||
obj.MaxStamina = 456
|
||||
obj.Spawn
|
||||
obj.Health mustEqual 123
|
||||
obj.Stamina mustEqual 456
|
||||
obj.MaxHealth mustEqual 123
|
||||
obj.MaxStamina mustEqual 456
|
||||
obj.MaxHealth = None
|
||||
//MaxStamina has no equivalent
|
||||
obj.MaxHealth mustEqual 100
|
||||
obj.MaxStamina mustEqual 456
|
||||
}
|
||||
|
||||
// "set new values (health, armor, stamina) but only when alive" in {
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class ProjectileTest extends Specification {
|
|||
SourceEntry(fury) match {
|
||||
case o : VehicleSource =>
|
||||
o.Name mustEqual "Fury"
|
||||
o.Faction mustEqual PlanetSideEmpire.TR
|
||||
o.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
o.Definition mustEqual GlobalDefinitions.fury
|
||||
o.Health mustEqual 650
|
||||
o.Shields mustEqual 0
|
||||
|
|
@ -303,13 +303,12 @@ class ProjectileTest extends Specification {
|
|||
val fury_dm = fury.DamageModel
|
||||
|
||||
"construct" in {
|
||||
val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, PlayerSource(player2), fury_dm, Vector3(1.2f, 3.4f, 5.6f), 123456L)
|
||||
val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, PlayerSource(player2), fury_dm, Vector3(1.2f, 3.4f, 5.6f))
|
||||
obj.resolution mustEqual ProjectileResolution.Hit
|
||||
obj.projectile mustEqual projectile
|
||||
obj.target mustEqual p2_source
|
||||
obj.damage_model mustEqual fury.DamageModel
|
||||
obj.hit_pos mustEqual Vector3(1.2f, 3.4f, 5.6f)
|
||||
obj.hit_time mustEqual 123456L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
400
common/src/test/scala/objects/RepairableTest.scala
Normal file
400
common/src/test/scala/objects/RepairableTest.scala
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.generator.{Generator, GeneratorControl}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalControl}
|
||||
import net.psforever.objects.serverobject.turret.{FacilityTurret, FacilityTurretControl}
|
||||
import net.psforever.objects.vehicles.VehicleControl
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.{InventoryStateMessage, RepairMessage}
|
||||
import net.psforever.types._
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/*
|
||||
the generator is used to test basic entity repair
|
||||
essentially, treat it more as a generic entity whose object type is repairable
|
||||
see GeneratorTest in relation to what the generator does above and beyond that during repair
|
||||
*/
|
||||
class RepairableEntityRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //4 & 5
|
||||
guid.register(tool, 4)
|
||||
guid.register(tool.AmmoSlot.Box, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"RepairableEntity" should {
|
||||
"handle repairs" in {
|
||||
assert(gen.Health == gen.Definition.DefaultHealth) //ideal
|
||||
val originalHealth = gen.Health -= 50
|
||||
assert(gen.Health < gen.Definition.DefaultHealth) //damage
|
||||
gen.Actor ! CommonMessages.Use(player1, Some(tool)) //repair
|
||||
|
||||
val msg123 = avatarProbe.receiveN(3, 500 milliseconds)
|
||||
assert(
|
||||
msg123.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg123(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg123(2) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(originalHealth < gen.Health) //generator repaired a bit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepairableEntityNotRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val gen = Generator(GlobalDefinitions.generator) //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
guid.register(building, 1)
|
||||
guid.register(gen, 2)
|
||||
guid.register(player1, 3)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = gen
|
||||
gen.Position = Vector3(1, 0, 0)
|
||||
gen.Actor = system.actorOf(Props(classOf[GeneratorControl], gen), "generator-control")
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //4 & 5
|
||||
guid.register(tool, 4)
|
||||
guid.register(tool.AmmoSlot.Box, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"RepairableEntity" should {
|
||||
"not repair if health is already full" in {
|
||||
assert(gen.Health == gen.Definition.DefaultHealth) //ideal
|
||||
gen.Actor ! CommonMessages.Use(player1, Some(tool)) //repair?
|
||||
avatarProbe.expectNoMsg(1000 milliseconds) //no messages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepairableAmenityTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val term = Terminal(GlobalDefinitions.order_terminal) //guid=2
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
guid.register(building, 1)
|
||||
guid.register(term, 2)
|
||||
guid.register(player1, 3)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = term
|
||||
term.Position = Vector3(1, 0, 0)
|
||||
term.Actor = system.actorOf(Props(classOf[TerminalControl], term), "terminal-control")
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //4 & 5
|
||||
guid.register(tool, 4)
|
||||
guid.register(tool.AmmoSlot.Box, 5)
|
||||
expectNoMsg(200 milliseconds)
|
||||
//we're not testing that the math is correct
|
||||
|
||||
"RepairableAmenity" should {
|
||||
"send initialization messages upon restoration" in {
|
||||
//the decimator does enough damage to one-shot this terminal from any initial health
|
||||
val originalHealth = term.Health = term.Definition.RepairRestoresAt - 1 //initial state manip
|
||||
term.Destroyed = true
|
||||
assert(originalHealth < term.Definition.RepairRestoresAt)
|
||||
assert(term.Destroyed)
|
||||
|
||||
term.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg12345 = avatarProbe.receiveN(5, 500 milliseconds)
|
||||
assert(
|
||||
msg12345.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(2) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 50, 0)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(3) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 51, 0)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(4) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(term.Health > term.Definition.RepairRestoresAt)
|
||||
assert(!term.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepairableTurretWeapon extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = Building("test-building", 1, 1, zone, StructureType.Facility) //guid=1
|
||||
val activityProbe = TestProbe()
|
||||
val avatarProbe = TestProbe()
|
||||
val vehicleProbe = TestProbe()
|
||||
val buildingProbe = TestProbe()
|
||||
zone.Activity = activityProbe.ref
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
zone.VehicleEvents = vehicleProbe.ref
|
||||
building.Actor = buildingProbe.ref
|
||||
|
||||
val turret = new FacilityTurret(GlobalDefinitions.manned_turret) //2, 5, 6
|
||||
turret.Actor = system.actorOf(Props(classOf[FacilityTurretControl], turret), "turret-control")
|
||||
turret.Zone = zone
|
||||
turret.Position = Vector3(1, 0, 0)
|
||||
val turretWeapon = turret.Weapons.values.head.Equipment.get.asInstanceOf[Tool]
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 2, 2)
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(turret, 2)
|
||||
guid.register(player1, 3)
|
||||
guid.register(turretWeapon, 5)
|
||||
guid.register(turretWeapon.AmmoSlot.Box, 6)
|
||||
building.Position = Vector3(1, 0, 0)
|
||||
building.Zone = zone
|
||||
building.Amenities = turret
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //7 & 8
|
||||
guid.register(tool, 7)
|
||||
guid.register(tool.AmmoSlot.Box, 8)
|
||||
|
||||
"RepairableTurretWeapon" should {
|
||||
"handle repairs and restoration" in {
|
||||
turret.Health = turret.Definition.RepairRestoresAt - 1 //initial state manip
|
||||
turret.Destroyed = true //initial state manip
|
||||
assert(turret.Health < turret.Definition.RepairRestoresAt)
|
||||
assert(turret.Destroyed)
|
||||
|
||||
turret.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg12345 = avatarProbe.receiveN(5, 500 milliseconds)
|
||||
val msg4 = vehicleProbe.receiveOne(500 milliseconds)
|
||||
assert(
|
||||
msg12345.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg12345(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
//msg12345(2) and msg12345(3) are related to RepairableAmenity
|
||||
assert(
|
||||
msg12345(4) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg4 match {
|
||||
case VehicleServiceMessage("test", VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(turret.Health > turret.Definition.RepairRestoresAt)
|
||||
assert(!turret.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepairableVehicleRepair extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val atv = Vehicle(GlobalDefinitions.quadassault) //guid=1, 2, 3
|
||||
atv.Actor = system.actorOf(Props(classOf[VehicleControl], atv), "vehicle-control")
|
||||
atv.Position = Vector3(1,0,0)
|
||||
val atvWeapon = atv.Weapons(1).Equipment.get.asInstanceOf[Tool]
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=4
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 2, 2)
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
guid.register(atv, 1)
|
||||
guid.register(atvWeapon, 2)
|
||||
guid.register(atvWeapon.AmmoSlot.Box, 3)
|
||||
guid.register(player1, 4)
|
||||
atv.Zone = zone
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //5 & 6
|
||||
guid.register(tool, 5)
|
||||
guid.register(tool.AmmoSlot.Box, 6)
|
||||
|
||||
"RepairableVehicle" should {
|
||||
"handle repairs" in {
|
||||
val originalHealth = atv.Health = atv.Definition.DamageDestroysAt + 1 //initial state manip
|
||||
assert(atv.Health == originalHealth)
|
||||
|
||||
atv.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
val msg123 = avatarProbe.receiveN(3, 500 milliseconds)
|
||||
assert(
|
||||
msg123.head match {
|
||||
case AvatarServiceMessage("TestCharacter1",
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(6), _, PlanetSideGUID(5), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg123(1) match {
|
||||
case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(
|
||||
msg123(2) match {
|
||||
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(1), _))) => true
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
assert(atv.Health > originalHealth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepairableVehicleRestoration extends ActorTest {
|
||||
/*
|
||||
no messages are dispatched, in this case, because most vehicles are flagged to not be repairable if destroyed
|
||||
*/
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val avatarProbe = TestProbe()
|
||||
zone.AvatarEvents = avatarProbe.ref
|
||||
|
||||
val atv = Vehicle(GlobalDefinitions.quadassault) //guid=1, 2, 3
|
||||
atv.Actor = system.actorOf(Props(classOf[VehicleControl], atv), "vehicle-control")
|
||||
atv.Position = Vector3(1,0,0)
|
||||
val atvWeapon = atv.Weapons(1).Equipment.get.asInstanceOf[Tool]
|
||||
|
||||
val player1 = Player(Avatar("TestCharacter1", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=4
|
||||
player1.Spawn
|
||||
player1.Position = Vector3(2, 2, 2)
|
||||
val player1Probe = TestProbe()
|
||||
player1.Actor = player1Probe.ref
|
||||
|
||||
guid.register(atv, 1)
|
||||
guid.register(atvWeapon, 2)
|
||||
guid.register(atvWeapon.AmmoSlot.Box, 3)
|
||||
guid.register(player1, 4)
|
||||
atv.Zone = zone
|
||||
|
||||
val tool = Tool(GlobalDefinitions.nano_dispenser) //5 & 6
|
||||
guid.register(tool, 5)
|
||||
guid.register(tool.AmmoSlot.Box, 6)
|
||||
|
||||
"RepairableVehicle" should {
|
||||
"will not restore a destroyed vehicle to working order" in {
|
||||
atv.Health = atv.Definition.DamageDestroysAt - 1 //initial state manip
|
||||
atv.Destroyed = true //initial state manip
|
||||
assert(atv.Health <= atv.Definition.DamageDestroysAt)
|
||||
assert(atv.Destroyed)
|
||||
|
||||
atv.Actor ! CommonMessages.Use(player1, Some(tool))
|
||||
avatarProbe.expectNoMsg(500 milliseconds)
|
||||
assert(atv.Health == 0) //set to zero explicitly
|
||||
assert(atv.Destroyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object RepairableTest { }
|
||||
|
|
@ -5,11 +5,12 @@ import akka.actor.{Actor, Props}
|
|||
import akka.routing.RandomPool
|
||||
import akka.testkit.TestProbe
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.guid.TaskResolver
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
|
||||
import net.psforever.objects.guid.{NumberPoolHub, TaskResolver}
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.resourcesilo.{ResourceSilo, ResourceSiloControl, ResourceSiloDefinition}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects.zones.{Zone, ZoneActor, ZoneMap}
|
||||
import net.psforever.packet.game.UseItemMessage
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -77,16 +78,34 @@ class ResourceSiloControlStartupTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlUseTest extends ActorTest {
|
||||
val serviceManager = ServiceManager.boot(system)
|
||||
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]), "taskResolver")
|
||||
val probe = TestProbe()
|
||||
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe), "avatar")
|
||||
val msg = UseItemMessage(PlanetSideGUID(1), PlanetSideGUID(0), PlanetSideGUID(2), 0L, false, Vector3(0f,0f,0f),Vector3(0f,0f,0f),0,0,0,0L) //faked
|
||||
val obj = ResourceSilo()
|
||||
obj.GUID = PlanetSideGUID(1)
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val map = new ZoneMap("test")
|
||||
val zone = new Zone("test", map, 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-zone-actor")
|
||||
zone.Actor ! Zone.Init()
|
||||
val building = new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building) //guid=1
|
||||
|
||||
val obj = ResourceSilo() //guid=2
|
||||
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
|
||||
obj.Owner = building
|
||||
obj.Actor ! "startup"
|
||||
|
||||
val player = Player(new Avatar(0L, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)) //guid=3
|
||||
val vehicle = Vehicle(GlobalDefinitions.ant) //guid=4
|
||||
|
||||
guid.register(building, 1)
|
||||
guid.register(obj, 2)
|
||||
guid.register(player, 3)
|
||||
guid.register(vehicle, 4)
|
||||
zone.Transport ! Zone.Vehicle.Spawn(vehicle)
|
||||
vehicle.Seats(0).Occupant = player
|
||||
player.VehicleSeated = vehicle.GUID
|
||||
val msg = UseItemMessage(PlanetSideGUID(1), PlanetSideGUID(0), PlanetSideGUID(2), 0L, false, Vector3.Zero,Vector3.Zero,0,0,0,0L) //faked
|
||||
expectNoMsg(200 milliseconds)
|
||||
|
||||
"Resource silo" should {
|
||||
"respond when being used" in {
|
||||
expectNoMsg(1 seconds)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ import akka.actor.{Actor, ActorRef, Props}
|
|||
import base.ActorTest
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable._
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
|
@ -38,7 +40,6 @@ class UtilityTest extends Specification {
|
|||
}
|
||||
|
||||
"create an ams_respawn_tube object" in {
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
val obj = Utility(UtilityType.ams_respawn_tube, UtilityTest.vehicle)
|
||||
obj.UtilType mustEqual UtilityType.ams_respawn_tube
|
||||
obj().isInstanceOf[SpawnTube] mustEqual true
|
||||
|
|
@ -54,17 +55,18 @@ class UtilityTest extends Specification {
|
|||
obj().asInstanceOf[Terminal].Actor mustEqual ActorRef.noSender
|
||||
}
|
||||
|
||||
"teleportpad_terminal produces a telepad object (router_telepad)" in {
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, TransactionType}
|
||||
"produce a telepad object through the teleportpad_terminal" in {
|
||||
val veh = Vehicle(GlobalDefinitions.quadstealth)
|
||||
veh.Faction = PlanetSideEmpire.TR
|
||||
val obj = Utility(UtilityType.teleportpad_terminal, UtilityTest.vehicle)
|
||||
val player = Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
veh.GUID = PlanetSideGUID(101)
|
||||
obj().Owner = veh //hack
|
||||
obj().GUID = PlanetSideGUID(1)
|
||||
player.GUID = PlanetSideGUID(2)
|
||||
|
||||
val msg = obj().asInstanceOf[Terminal].Request(
|
||||
Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute)),
|
||||
player,
|
||||
ItemTransactionMessage(PlanetSideGUID(853), TransactionType.Buy, 0, "router_telepad", 0, PlanetSideGUID(0))
|
||||
)
|
||||
msg.isInstanceOf[Terminal.BuyEquipment] mustEqual true
|
||||
|
|
@ -83,13 +85,13 @@ class UtilityTest extends Specification {
|
|||
val obj = Utility(UtilityType.internal_router_telepad_deployable, UtilityTest.vehicle)
|
||||
val inpad = obj().asInstanceOf[Utility.InternalTelepad]
|
||||
|
||||
inpad.Telepad mustEqual None
|
||||
inpad.Telepad.isEmpty mustEqual true
|
||||
inpad.Telepad = PlanetSideGUID(5)
|
||||
inpad.Telepad mustEqual Some(PlanetSideGUID(5))
|
||||
inpad.Telepad.contains(PlanetSideGUID(5)) mustEqual true
|
||||
inpad.Telepad = PlanetSideGUID(6)
|
||||
inpad.Telepad mustEqual Some(PlanetSideGUID(6))
|
||||
inpad.Telepad.contains(PlanetSideGUID(6)) mustEqual true
|
||||
inpad.Telepad = None
|
||||
inpad.Telepad mustEqual None
|
||||
inpad.Telepad.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"be located with their owner (terminal)" in {
|
||||
|
|
@ -98,7 +100,6 @@ class UtilityTest extends Specification {
|
|||
obj().Position mustEqual veh.Position
|
||||
obj().Orientation mustEqual veh.Orientation
|
||||
|
||||
import net.psforever.types.Vector3
|
||||
veh.Position = Vector3(1, 2, 3)
|
||||
veh.Orientation = Vector3(4, 5, 6)
|
||||
obj().Position mustEqual veh.Position
|
||||
|
|
@ -111,7 +112,6 @@ class UtilityTest extends Specification {
|
|||
obj().Position mustEqual veh.Position
|
||||
obj().Orientation mustEqual veh.Orientation
|
||||
|
||||
import net.psforever.types.Vector3
|
||||
veh.Position = Vector3(1, 2, 3)
|
||||
veh.Orientation = Vector3(4, 5, 6)
|
||||
obj().Position mustEqual veh.Position
|
||||
|
|
@ -124,13 +124,12 @@ class UtilityTest extends Specification {
|
|||
obj().Position mustEqual veh.Position
|
||||
obj().Orientation mustEqual veh.Orientation
|
||||
|
||||
import net.psforever.types.Vector3
|
||||
veh.Position = Vector3(1, 2, 3)
|
||||
veh.Orientation = Vector3(4, 5, 6)
|
||||
veh.GUID = PlanetSideGUID(101)
|
||||
obj().Position mustEqual veh.Position
|
||||
obj().Orientation mustEqual veh.Orientation
|
||||
obj().asInstanceOf[Utility.InternalTelepad].Router mustEqual Some(veh.GUID)
|
||||
obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID) mustEqual true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ class VehicleControlStopMountingTest extends ActorTest {
|
|||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player(VehicleTest.avatar2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
|
|
@ -349,6 +350,7 @@ class VehicleControlRestartMountingTest extends ActorTest {
|
|||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
|
|
@ -380,6 +382,7 @@ class VehicleControlAlwaysDismountTest extends ActorTest {
|
|||
val player2 = Player(VehicleTest.avatar2)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
|
|
@ -430,6 +433,7 @@ class VehicleControlMountingBlockedExosuitTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
|
|
@ -490,6 +494,7 @@ class VehicleControlMountingBlockedSeatPermissionTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
|
|
@ -524,6 +529,7 @@ class VehicleControlMountingDriverSeatTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
|
|
@ -563,6 +569,7 @@ class VehicleControlMountingOwnedLockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
|
|
@ -602,6 +609,7 @@ class VehicleControlMountingOwnedUnlockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
val vehicle = Vehicle(GlobalDefinitions.apc_tr)
|
||||
vehicle.Faction = PlanetSideEmpire.TR
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
val player1 = Player(VehicleTest.avatar1)
|
||||
|
|
@ -630,34 +638,6 @@ class VehicleControlMountingOwnedUnlockedDriverSeatTest extends ActorTest {
|
|||
}
|
||||
}
|
||||
|
||||
class VehicleControlRepairTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
vehicle.GUID = PlanetSideGUID(10)
|
||||
vehicle.Health = 50
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
vehicle.Zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
VehicleEvents = probe.ref
|
||||
}
|
||||
|
||||
"Can repair alive vehicle" in {
|
||||
assert(vehicle.Health == 50)
|
||||
|
||||
vehicle.Health += 10
|
||||
assert(vehicle.Health == 60)
|
||||
}
|
||||
|
||||
"Can't repair dead vehicle" in {
|
||||
assert(vehicle.Health > 0)
|
||||
|
||||
vehicle.Health = 0
|
||||
assert(vehicle.Health == 0)
|
||||
|
||||
vehicle.Health += 10
|
||||
assert(vehicle.Health == 0)
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControlShieldsChargingTest extends ActorTest {
|
||||
val probe = new TestProbe(system)
|
||||
val vehicle = Vehicle(GlobalDefinitions.fury)
|
||||
|
|
@ -767,7 +747,7 @@ class VehicleControlShieldsNotChargingTooEarlyTest extends ActorTest {
|
|||
// 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)
|
||||
// val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, p_source, fury_dm, Vector3(1.2f, 3.4f, 5.6f))
|
||||
//
|
||||
// "not charge vehicle shields if recently damaged" in {
|
||||
// assert(vehicle.Shields == 0)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@ package objects.terminal
|
|||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import base.ActorTest
|
||||
import net.psforever.objects.definition.SeatDefinition
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.implantmech.{ImplantTerminalMech, ImplantTerminalMechControl}
|
||||
import net.psforever.objects.serverobject.structures.StructureType
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.vehicles.Seat
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -24,7 +28,7 @@ class ImplantTerminalMechTest extends Specification {
|
|||
implant_terminal_mech.Seats(0).isInstanceOf[SeatDefinition] mustEqual true
|
||||
implant_terminal_mech.Seats(0).ArmorRestriction mustEqual net.psforever.objects.vehicles.SeatArmorRestriction.NoMax
|
||||
implant_terminal_mech.Seats(0).Bailable mustEqual false
|
||||
implant_terminal_mech.Seats(0).ControlledWeapon mustEqual None
|
||||
implant_terminal_mech.Seats(0).ControlledWeapon.isEmpty mustEqual true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,19 +43,19 @@ class ImplantTerminalMechTest extends Specification {
|
|||
|
||||
"get seat from mount points" in {
|
||||
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
obj.GetSeatFromMountPoint(0) mustEqual None
|
||||
obj.GetSeatFromMountPoint(1) mustEqual Some(0)
|
||||
obj.GetSeatFromMountPoint(2) mustEqual None
|
||||
obj.GetSeatFromMountPoint(0).isEmpty mustEqual true
|
||||
obj.GetSeatFromMountPoint(1).contains(0) mustEqual true
|
||||
obj.GetSeatFromMountPoint(2).isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"get passenger in a seat" in {
|
||||
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
obj.PassengerInSeat(player) mustEqual None
|
||||
obj.PassengerInSeat(player).isEmpty mustEqual true
|
||||
obj.Seats(0).Occupant = player
|
||||
obj.PassengerInSeat(player) mustEqual Some(0)
|
||||
obj.PassengerInSeat(player).contains(0) mustEqual true
|
||||
obj.Seats(0).Occupant = None
|
||||
obj.PassengerInSeat(player) mustEqual None
|
||||
obj.PassengerInSeat(player).isEmpty mustEqual true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +117,7 @@ class ImplantTerminalMechControl4Test extends ActorTest {
|
|||
"dismount player after mounting" in {
|
||||
val (player, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
mech.Actor ! Mountable.TryMount(player, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //consume reply
|
||||
receiveOne(Duration.create(200, "ms")) //consume reply
|
||||
assert(mech.Seat(0).get.isOccupied)
|
||||
|
||||
mech.Actor ! Mountable.TryDismount(player, 0)
|
||||
|
|
@ -155,14 +159,26 @@ class ImplantTerminalMechControl5Test extends ActorTest {
|
|||
|
||||
object ImplantTerminalMechTest {
|
||||
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, ImplantTerminalMech) = {
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
val terminal = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], terminal), "mech")
|
||||
terminal.Owner = new Building("Building", building_guid = 0, map_id = 0, Zone.Nowhere, StructureType.Building, GlobalDefinitions.building)
|
||||
terminal.Owner.Faction = faction
|
||||
terminal.GUID = PlanetSideGUID(1)
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val map = new ZoneMap("test")
|
||||
val zone = new Zone("test", map, 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
}
|
||||
val building = new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building) //guid=3
|
||||
building.Faction = faction
|
||||
|
||||
val interface = Terminal(GlobalDefinitions.implant_terminal_interface) //guid=2
|
||||
interface.Owner = building
|
||||
val terminal = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech) //guid=1
|
||||
terminal.Owner = building
|
||||
|
||||
guid.register(terminal, 1)
|
||||
guid.register(interface, 2)
|
||||
guid.register(building, 3)
|
||||
map.TerminalToInterface(1, 2)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], terminal), "terminal-control")
|
||||
|
||||
(Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)), terminal)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue