diff --git a/common/src/main/scala/net/psforever/objects/Vehicle.scala b/common/src/main/scala/net/psforever/objects/Vehicle.scala index 2d2a7292..6b2adfb7 100644 --- a/common/src/main/scala/net/psforever/objects/Vehicle.scala +++ b/common/src/main/scala/net/psforever/objects/Vehicle.scala @@ -77,6 +77,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends AmenityOwner private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.TR private var health : Int = 1 private var shields : Int = 0 + private var isDead : Boolean = false private var decal : Int = 0 private var trunkAccess : Option[PlanetSideGUID] = None private var jammered : Boolean = false @@ -140,12 +141,23 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends AmenityOwner MountedIn } + def IsDead : Boolean = { + isDead + } + def Health : Int = { health } def Health_=(assignHealth : Int) : Int = { - health = math.min(math.max(0, assignHealth), MaxHealth) + if(!isDead) { + health = math.min(math.max(0, assignHealth), MaxHealth) + } + + if(health == 0) { + isDead = true + } + health } diff --git a/common/src/test/scala/objects/VehicleTest.scala b/common/src/test/scala/objects/VehicleTest.scala index eebf812d..d7897078 100644 --- a/common/src/test/scala/objects/VehicleTest.scala +++ b/common/src/test/scala/objects/VehicleTest.scala @@ -630,6 +630,34 @@ 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) diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 85f47b1d..7fe05cf9 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -861,7 +861,7 @@ class WorldSessionActor extends Actor case Zone.Lattice.SpawnPoint(zone_id, spawn_tube) => var (pos, ori) = spawn_tube.SpecificPoint(continent.GUID(player.VehicleSeated) match { - case Some(obj : Vehicle) if obj.Health > 0 => + case Some(obj : Vehicle) if !obj.IsDead => obj case _ => player @@ -3172,8 +3172,7 @@ class WorldSessionActor extends Actor if(!target.HasGUID) { // Target is gone, cancel the hack. - // Note: I couldn't find any examples of an object that no longer has a GUID in packet captures, but sending the hacking player's GUID as the target to cancel the hack seems to work - sendResponse(HackMessage(progressType, player.GUID, player.GUID, 0, 0L, HackState.Cancelled, 8L)) + sendResponse(HackMessage(progressType, target.GUID, player.GUID, 0, 0L, HackState.Cancelled, 8L)) } else if(vis == HackState.Cancelled) { // Object moved. Cancel the hack (e.g. vehicle drove away) @@ -5171,9 +5170,8 @@ class WorldSessionActor extends Actor else if(equipment.isDefined) { equipment.get.Definition match { case GlobalDefinitions.nano_dispenser => - //TODO repairing behavior if (!player.isMoving && Vector3.Distance(player.Position, obj.Position) < 5) { - if (obj.Health < obj.MaxHealth) { + if (obj.Health < obj.MaxHealth && !obj.IsDead) { obj.Health += 48 // sendResponse(QuantityUpdateMessage(PlanetSideGUID(8214),ammo_quantity_left)) val RepairPercent: Int = obj.Health * 100 / obj.MaxHealth @@ -5918,7 +5916,7 @@ class WorldSessionActor extends Actor case Some(vehicleGUID) => continent.GUID(vehicleGUID) match { case Some(obj : Vehicle) => - if(obj.Health > 0) { //vehicle will try to charge even if destroyed + if(!obj.IsDead) { //vehicle will try to charge even if destroyed obj.Actor ! Vehicle.ChargeShields(15) } case _ => @@ -8311,7 +8309,7 @@ class WorldSessionActor extends Actor } else { continent.GUID(player.VehicleSeated) match { - case Some(obj : Vehicle) if obj.Health > 0 => + case Some(obj : Vehicle) if !obj.IsDead => cluster ! Zone.Lattice.RequestSpawnPoint(sanctNumber, tplayer, 12) //warp gates for functioning vehicles case None => cluster ! Zone.Lattice.RequestSpawnPoint(sanctNumber, tplayer, 7) //player character spawns