PSF-BotServer/common/src/test/scala/objects/ProjectileTest.scala

315 lines
10 KiB
Scala
Raw Normal View History

// Copyright (c) 2017 PSForever
package objects
2018-07-30 09:28:45 -04:00
import net.psforever.objects._
import net.psforever.objects.ballistics._
import net.psforever.objects.definition.ProjectileDefinition
2018-07-30 09:28:45 -04:00
import net.psforever.objects.serverobject.mblocker.Locker
import net.psforever.objects.vital.DamageType
import net.psforever.types.{PlanetSideGUID, _}
import org.specs2.mutable.Specification
class ProjectileTest extends Specification {
2018-07-30 09:28:45 -04:00
val player = Player(Avatar("TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
val fury = Vehicle(GlobalDefinitions.fury)
"LocalProjectile" should {
"construct" in {
val obj = new LocalProjectile() //since they're just placeholders, they only need to construct
obj.Definition.ObjectId mustEqual 0
obj.Definition.Name mustEqual "projectile"
}
2018-07-30 09:28:45 -04:00
"local projectile range" in {
Projectile.BaseUID < Projectile.RangeUID mustEqual true
}
}
"ProjectileDefinition" should {
"define (default)" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.ProjectileType mustEqual Projectiles.bullet_9mm_projectile
obj.ObjectId mustEqual 31
obj.Damage0 mustEqual 0
obj.Damage1 mustEqual 0
obj.Damage2 mustEqual 0
obj.Damage3 mustEqual 0
obj.Damage4 mustEqual 0
obj.Acceleration mustEqual 0
obj.AccelerationUntil mustEqual 0f
obj.ProjectileDamageType mustEqual DamageType.None
obj.ProjectileDamageTypeSecondary mustEqual DamageType.None
obj.DegradeDelay mustEqual 1f
obj.DegradeMultiplier mustEqual 1f
obj.InitialVelocity mustEqual 1
obj.Lifespan mustEqual 1f
obj.DamageAtEdge mustEqual 1f
obj.DamageRadius mustEqual 1f
obj.UseDamage1Subtract mustEqual false
}
"define (custom)" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.Damage0 = 2
obj.Damage1 = 4
obj.Damage2 = 8
obj.Damage3 = 16
obj.Damage4 = 32
obj.Acceleration = 5
obj.AccelerationUntil = 5.5f
obj.ProjectileDamageType = DamageType.Splash
obj.ProjectileDamageTypeSecondary = DamageType.Radiation
obj.DegradeDelay = 11.1f
obj.DegradeMultiplier = 22.2f
obj.InitialVelocity = 50
obj.Lifespan = 11.2f
obj.DamageAtEdge = 3f
obj.DamageRadius = 3f
obj.UseDamage1Subtract = true
obj.Damage0 mustEqual 2
obj.Damage1 mustEqual 4
obj.Damage2 mustEqual 8
obj.Damage3 mustEqual 16
obj.Damage4 mustEqual 32
obj.Acceleration mustEqual 5
obj.AccelerationUntil mustEqual 5.5f
obj.ProjectileDamageType mustEqual DamageType.Splash
obj.ProjectileDamageTypeSecondary mustEqual DamageType.Radiation
obj.DegradeDelay mustEqual 11.1f
obj.DegradeMultiplier mustEqual 22.2f
obj.InitialVelocity mustEqual 50
obj.Lifespan mustEqual 11.2f
obj.DamageAtEdge mustEqual 3f
obj.DamageRadius mustEqual 3f
obj.UseDamage1Subtract mustEqual true
}
"define (failure)" in {
Projectiles(31) mustEqual Projectiles.bullet_9mm_projectile
try {
ProjectileDefinition(Projectiles.bullet_9mm_projectile) //passes
}
catch {
case _ : NoSuchElementException =>
ko
}
Projectiles(2) must throwA[NoSuchElementException]
new ProjectileDefinition(2) must throwA[NoSuchElementException]
}
"cascade damage values" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.Damage4 = 32
obj.Damage3 = 16
obj.Damage2 = 8
obj.Damage1 = 4
obj.Damage0 = 2
//initial
obj.Damage4 mustEqual 32
obj.Damage3 mustEqual 16
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage4
obj.Damage4 = None
obj.Damage4 mustEqual 16
obj.Damage3 mustEqual 16
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage3
obj.Damage3 = None
obj.Damage4 mustEqual 8
obj.Damage3 mustEqual 8
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage2
obj.Damage2 = None
obj.Damage4 mustEqual 4
obj.Damage3 mustEqual 4
obj.Damage2 mustEqual 4
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage1
obj.Damage1 = None
obj.Damage4 mustEqual 2
obj.Damage3 mustEqual 2
obj.Damage2 mustEqual 2
obj.Damage1 mustEqual 2
obj.Damage0 mustEqual 2
//negate Damage0
obj.Damage0 = None
obj.Damage4 mustEqual 0
obj.Damage3 mustEqual 0
obj.Damage2 mustEqual 0
obj.Damage1 mustEqual 0
obj.Damage0 mustEqual 0
//set Damage3, set Damage0
obj.Damage3 = 13
obj.Damage0 = 7
obj.Damage4 mustEqual 13
obj.Damage3 mustEqual 13
obj.Damage2 mustEqual 7
obj.Damage1 mustEqual 7
obj.Damage0 mustEqual 7
}
}
2018-07-30 09:28:45 -04:00
"SourceEntry" should {
"construct for players" in {
SourceEntry(player) match {
case o : PlayerSource =>
o.Name mustEqual "TestCharacter"
o.Faction mustEqual PlanetSideEmpire.TR
o.Seated mustEqual false
o.ExoSuit mustEqual ExoSuitType.Standard
o.Health mustEqual 0
o.Armor mustEqual 0
o.Definition mustEqual GlobalDefinitions.avatar
o.Position mustEqual Vector3.Zero
o.Orientation mustEqual Vector3.Zero
o.Velocity mustEqual None
case _ =>
ko
}
}
"construct for vehicles" in {
SourceEntry(fury) match {
case o : VehicleSource =>
o.Name mustEqual "Fury"
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
2020-04-14 15:17:32 -04:00
o.Faction mustEqual PlanetSideEmpire.NEUTRAL
2018-07-30 09:28:45 -04:00
o.Definition mustEqual GlobalDefinitions.fury
o.Health mustEqual 650
o.Shields mustEqual 0
o.Position mustEqual Vector3.Zero
o.Orientation mustEqual Vector3.Zero
o.Velocity mustEqual None
case _ =>
ko
}
}
"construct for generic object" in {
val obj = Locker()
SourceEntry(obj) match {
case o : ObjectSource =>
o.obj mustEqual obj
o.Name mustEqual "Mb Locker"
o.Faction mustEqual PlanetSideEmpire.NEUTRAL
o.Definition mustEqual GlobalDefinitions.mb_locker
o.Position mustEqual Vector3.Zero
o.Orientation mustEqual Vector3.Zero
o.Velocity mustEqual None
case _ =>
ko
}
}
"contain timely information" in {
val obj = Player(Avatar("TestCharacter-alt", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
obj.VehicleSeated = Some(PlanetSideGUID(1))
obj.Position = Vector3(1.2f, 3.4f, 5.6f)
obj.Orientation = Vector3(2.1f, 4.3f, 6.5f)
obj.Velocity = Some(Vector3(1.1f, 2.2f, 3.3f))
val sobj = SourceEntry(obj)
obj.VehicleSeated = None
obj.Position = Vector3.Zero
obj.Orientation = Vector3.Zero
obj.Velocity = None
obj.ExoSuit = ExoSuitType.Agile
sobj match {
case o : PlayerSource =>
o.Name mustEqual "TestCharacter-alt"
o.Faction mustEqual PlanetSideEmpire.TR
o.Seated mustEqual true
o.ExoSuit mustEqual ExoSuitType.Standard
o.Definition mustEqual GlobalDefinitions.avatar
o.Position mustEqual Vector3(1.2f, 3.4f, 5.6f)
o.Orientation mustEqual Vector3(2.1f, 4.3f, 6.5f)
o.Velocity mustEqual Some(Vector3(1.1f, 2.2f, 3.3f))
case _ =>
ko
}
}
}
"Projectile" should {
2018-07-30 09:28:45 -04:00
val beamer_def = GlobalDefinitions.beamer
val beamer_wep = Tool(beamer_def)
val firemode = beamer_wep.FireMode
val projectile = beamer_wep.Projectile
2018-07-30 09:28:45 -04:00
"construct" in {
val obj = Projectile(beamer_wep.Projectile, beamer_wep.Definition, beamer_wep.FireMode, PlayerSource(player), beamer_def.ObjectId, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
obj.profile mustEqual projectile
obj.tool_def mustEqual beamer_def
obj.fire_mode mustEqual firemode
obj.owner match {
case _ : PlayerSource =>
ok
case _ =>
ko
}
obj.attribute_to mustEqual obj.tool_def.ObjectId
obj.shot_origin mustEqual Vector3(1.2f, 3.4f, 5.6f)
obj.shot_angle mustEqual Vector3(0.2f, 0.4f, 0.6f)
obj.fire_time <= System.nanoTime mustEqual true
2018-07-30 09:28:45 -04:00
obj.isResolved mustEqual false
}
"construct (different attribute)" in {
val obj1 = Projectile(beamer_wep.Projectile, beamer_wep.Definition, beamer_wep.FireMode, player, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
obj1.attribute_to mustEqual obj1.tool_def.ObjectId
val obj2 = Projectile(beamer_wep.Projectile, beamer_wep.Definition, beamer_wep.FireMode, PlayerSource(player), 65, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
obj2.attribute_to == obj2.tool_def.ObjectId mustEqual false
obj2.attribute_to mustEqual 65
}
"resolve" in {
2018-07-30 09:28:45 -04:00
val obj = Projectile(projectile, beamer_def, firemode, PlayerSource(player), beamer_def.ObjectId, Vector3.Zero, Vector3.Zero)
obj.isResolved mustEqual false
obj.isMiss mustEqual false
2018-07-30 09:28:45 -04:00
obj.Resolve()
obj.isResolved mustEqual true
obj.isMiss mustEqual false
}
"missed" in {
val obj = Projectile(projectile, beamer_def, firemode, PlayerSource(player), beamer_def.ObjectId, Vector3.Zero, Vector3.Zero)
obj.isResolved mustEqual false
obj.isMiss mustEqual false
obj.Miss()
obj.isResolved mustEqual true
obj.isMiss mustEqual true
}
2018-07-30 09:28:45 -04:00
}
2018-07-30 09:28:45 -04:00
"ResolvedProjectile" should {
val beamer_wep = Tool(GlobalDefinitions.beamer)
val p_source = PlayerSource(player)
val player2 = Player(Avatar("TestTarget", PlanetSideEmpire.NC, CharacterGender.Female, 1, CharacterVoice.Mute))
val p2_source = PlayerSource(player2)
val projectile = Projectile(beamer_wep.Projectile, GlobalDefinitions.beamer, beamer_wep.FireMode, p_source, GlobalDefinitions.beamer.ObjectId, Vector3.Zero, Vector3.Zero)
val fury_dm = fury.DamageModel
"construct" in {
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
2020-04-14 15:17:32 -04:00
val obj = ResolvedProjectile(ProjectileResolution.Hit, projectile, PlayerSource(player2), fury_dm, Vector3(1.2f, 3.4f, 5.6f))
2018-07-30 09:28:45 -04:00
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)
}
}
}