diff --git a/common/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/common/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 1724651e..e3a27b9d 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -80,7 +80,7 @@ trait RepairableEntity extends Repairable { val name = player.Name val tguid = target.GUID val originalHealth = target.Health - val updatedHealth = if(!(player.isMoving || target.isMoving)) { //only allow stationary repairs + val updatedHealth = if(!(player.isMoving(1f) || target.isMoving(1f))) { //only allow stationary repairs within margin of error val newHealth = target.Health = originalHealth + Repairable.Quality + RepairValue(item) + definition.RepairMod val zoneId = zone.Id val magazine = item.Discharge diff --git a/common/src/main/scala/net/psforever/objects/vehicles/VehicleControl.scala b/common/src/main/scala/net/psforever/objects/vehicles/VehicleControl.scala index 9f4e0ed9..c0fa10ff 100644 --- a/common/src/main/scala/net/psforever/objects/vehicles/VehicleControl.scala +++ b/common/src/main/scala/net/psforever/objects/vehicles/VehicleControl.scala @@ -83,6 +83,12 @@ class VehicleControl(vehicle : Vehicle) extends Actor case msg : Mountable.TryDismount => dismountBehavior.apply(msg) val obj = MountableObject + + // Reset velocity to zero when driver dismounts, to allow jacking/repair if vehicle was moving slightly before dismount + if(!obj.Seats(0).isOccupied) { + obj.Velocity = Some(Vector3.Zero) + } + if(!decaying && obj.Owner.isEmpty && obj.Seats.values.forall(!_.isOccupied)) { decaying = true decayTimer = context.system.scheduler.scheduleOnce(MountableObject.Definition.DeconstructionTime.getOrElse(5 minutes), self, VehicleControl.PrepareForDeletion()) diff --git a/common/src/main/scala/net/psforever/packet/game/VehicleStateMessage.scala b/common/src/main/scala/net/psforever/packet/game/VehicleStateMessage.scala index 5fdab405..3f61f2e6 100644 --- a/common/src/main/scala/net/psforever/packet/game/VehicleStateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/VehicleStateMessage.scala @@ -25,7 +25,7 @@ import scodec.codecs._ * 30 for hard left; * values in between are possible; * vehicles that hover also influence this field as expected - * @param unk5 na - Possibly a flag to indicate the vehicle is attached to something else e.g. is in a galaxy/lodestar cargo bay + * @param is_decelerating If the vehicle is decelerating (in any direction), i.e. if the brake lights are on. * @param is_cloaked vehicle is cloaked by virtue of being a Wraith or a Phantasm * @see `PlacementData` */ @@ -53,7 +53,7 @@ final case class VehicleStateMessage(vehicle_guid : PlanetSideGUID, unk3 : Int, unk4 : Int, wheel_direction : Int, - unk5 : Boolean, + is_decelerating : Boolean, is_cloaked : Boolean ) extends PlanetSideGamePacket { type Packet = VehicleStateMessage diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index a3ffd11b..96255cb9 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -634,6 +634,7 @@ class WorldSessionActor extends Actor } else if(state == DriveState.Deployed) { log.info(s"DeployRequest: $obj has been Deployed") + obj.Velocity = Some(Vector3.Zero) sendResponse(DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero)) continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero)) DeploymentActivities(obj) @@ -4148,7 +4149,7 @@ class WorldSessionActor extends Actor sendResponse(DropSession(sessionId, "kick by GM")) } - case msg@VehicleStateMessage(vehicle_guid, unk1, pos, ang, vel, flying, unk6, unk7, wheels, unk9, is_cloaked) => + case msg@VehicleStateMessage(vehicle_guid, unk1, pos, ang, vel, flying, unk6, unk7, wheels, is_decelerating, is_cloaked) => if(deadState == DeadState.Alive) { GetVehicleAndSeat() match { case (Some(obj), Some(0)) => @@ -4161,7 +4162,11 @@ class WorldSessionActor extends Actor obj.Position = pos obj.Orientation = ang if(obj.MountedIn.isEmpty) { - obj.Velocity = vel + if(obj.DeploymentState != DriveState.Deployed) { + obj.Velocity = vel + } else { + obj.Velocity = Some(Vector3.Zero) + } if(obj.Definition.CanFly) { obj.Flying = flying.nonEmpty //usually Some(7) } @@ -4176,7 +4181,7 @@ class WorldSessionActor extends Actor } else { None - }, unk6, unk7, wheels, unk9, obj.Cloaked)) + }, unk6, unk7, wheels, is_decelerating, obj.Cloaked)) updateSquad() case (None, _) => //log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")